import t, c
from stdint import *
from w32.win32base import *
from w32.win32process import CreateThread, GetExitCodeThread, GetCurrentThreadId, TlsAlloc, TlsFree, TlsGetValue, TlsSetValue
from w32.win32sync import WaitForSingleObject

# 全部导入锁类，用户也可按需导入
from lock import Lock
from event import Event
from condition import Condition
from rwlock import RWLock


@t.Object
class Thread:
    """线程类，封装 Windows CreateThread。

    线程回调签名: def thread_func(arg: t.CPtr) -> t.CPtr
    注意: Windows API 限制返回值为 DWORD(32位)，64位指针会被截断。
    如需返回 64 位结果，请通过 arg 参数结构体传递。

    用法:
        def worker(arg: t.CPtr) -> t.CPtr:
            # 线程逻辑
            return NULL

        t: Thread = Thread(worker, arg_ptr)
        t.start()
        t.join()
    """
    handle: HANDLE
    thread_id: ULONG
    target: VOIDPTR
    arg: VOIDPTR
    started: BOOL

    def __init__(self, target: VOIDPTR, arg: VOIDPTR = NULL):
        self.handle = NULL
        self.thread_id = 0
        self.target = target
        self.arg = arg
        self.started = FALSE

    def start(self):
        if self.started:
            return
        self.handle = CreateThread(NULL, 0, self.target, self.arg, 0, c.Addr(self.thread_id))
        self.started = TRUE

    def join(self, timeout_ms: ULONG = INFINITE) -> BOOL:
        if not self.started:
            return FALSE
        result: ULONG = WaitForSingleObject(self.handle, timeout_ms)
        return result == WAIT_OBJECT_0

    def is_alive(self) -> BOOL:
        if not self.started:
            return FALSE
        result: ULONG = WaitForSingleObject(self.handle, 0)
        return result == WAIT_TIMEOUT

    def get_exit_code(self) -> ULONG:
        code: ULONG = 0
        GetExitCodeThread(self.handle, c.Addr(code))
        return code

    def close(self):
        if self.handle != NULL:
            CloseHandle(self.handle)
            self.handle = NULL


@t.Object
class local:
    """TLS (Thread Local Storage) 封装。

    用法:
        tls: local = local()
        tls.set(value_ptr)
        val: t.CPtr = tls.get()
    """
    index: ULONG

    def __init__(self):
        self.index = TlsAlloc()

    def get(self) -> VOIDPTR:
        return TlsGetValue(self.index)

    def set(self, value: VOIDPTR) -> BOOL:
        return TlsSetValue(self.index, value)

    def free(self) -> BOOL:
        return TlsFree(self.index)


def get_current_thread_id() -> ULONG:
    """获取当前线程 ID"""
    return GetCurrentThreadId()


def sleep_ms(ms: ULONG):
    """让当前线程休眠指定毫秒数"""
    Sleep(ms)
