import t, c
from stdint import *
from w32.win32base import *
from w32.win32sync import (
    CRITICAL_SECTION,
    InitializeCriticalSection, EnterCriticalSection, LeaveCriticalSection, DeleteCriticalSection,
    InitializeConditionVariable, SleepConditionVariableCS,
    WakeConditionVariable, WakeAllConditionVariable
)


@t.Object
class Condition:
    """基于 Windows 条件变量的条件变量，内部包含 CRITICAL_SECTION。

    用法:
        cond: Condition = Condition()
        with cond:
            while not ready:
                cond.wait()
            cond.notify()
    """
    cond_var: VOIDPTR
    cs: CRITICAL_SECTION

    def __init__(self):
        InitializeCriticalSection(c.Addr(self.cs))
        InitializeConditionVariable(c.Addr(self.cond_var))

    def wait(self, timeout_ms: ULONG = INFINITE) -> BOOL:
        return SleepConditionVariableCS(c.Addr(self.cond_var), c.Addr(self.cs), timeout_ms)

    def notify(self):
        WakeConditionVariable(c.Addr(self.cond_var))

    def notify_all(self):
        WakeAllConditionVariable(c.Addr(self.cond_var))

    def acquire(self):
        EnterCriticalSection(c.Addr(self.cs))

    def release(self):
        LeaveCriticalSection(c.Addr(self.cs))

    def __enter__(self) -> 'Condition' | t.CPtr:
        self.acquire()
        return self

    def __exit__(self):
        self.release()

    def delete(self):
        DeleteCriticalSection(c.Addr(self.cs))
