import t, c
from stdint import *
import platmacro
import memhub
import string
import stdio

# Windows 后端依赖
import w32.win32base
import w32.win32process

# POSIX 后端依赖
import posix

# 模块级全局 MBuddy 指针（由用户在 main 中赋值初始化）
_mbuddy: memhub.MemBuddy | t.CPtr


# =============================================================================
# C 标准库 IO 声明
# =============================================================================

def fgets(buf: t.CChar | t.CPtr, size: t.CInt, stream: t.CVoid | t.CPtr) -> t.CChar | t.CPtr | t.CExtern | t.CExport: pass

def fflush(stream: t.CVoid | t.CPtr) -> t.CInt | t.CExtern | t.CExport: pass

# C 标准库 exit（刷新缓冲区后终止进程，跨平台）
def exit(status: INT) -> VOID | t.CExtern | t.CExport: pass


# =============================================================================
# 平台信息
# =============================================================================

# 最大整数值（64 位平台 ssize_t 上限）
maxsize: t.CDefine = 9223372036854775807


def platform() -> str:
    """返回平台标识字符串（'win32' 或 'linux'）"""
    if platmacro.IS_WINDOWS:
        return "win32"
    return "linux"


# =============================================================================
# 进程信息
# =============================================================================

def get_pid() -> int:
    """返回当前进程 ID"""
    if platmacro.IS_WINDOWS:
        return w32.win32process.GetCurrentProcessId()
    return posix.getpid()


# =============================================================================
# 命令行参数（argv）
# =============================================================================

# 全局 argv 状态（首次访问时初始化）
_argc: INT = 0
# _argv 是指针数组（char**），必须用 str | t.CPtr 使索引按 sizeof(char*) 步长
# str 本身是 char*，| t.CPtr 再加一层指针 = char**
# bytes | t.CPtr 也是 char**，可以同样用
_argv: str | t.CPtr


def _init_argv():
    """初始化全局 argv（首次访问时调用一次）"""
    global _argc, _argv
    if _argc != 0:
        return
    if platmacro.IS_WINDOWS:
        _init_argv_win32()
    else:
        _init_argv_posix()


def _init_argv_win32():
    """Windows：GetCommandLineA + 手动解析（处理空格/双引号/反斜杠）"""
    global _argc, _argv
    cmdline: CHARPTR = w32.win32base.GetCommandLineA()
    if cmdline == None:
        return
    cmdlen: t.CSizeT = string.strlen(cmdline)
    if cmdlen == 0:
        return

    # 分配参数字符串缓冲区（最坏情况：整个命令行 + argc 个 \0）
    buf: bytes = _mbuddy.alloc(cmdlen + 1)
    if buf == None:
        return

    # 分配指针数组（最坏情况：每个字符都是一个参数）
    max_args: t.CSizeT = cmdlen + 1
    argv_arr: str | t.CPtr = (str | t.CPtr)(_mbuddy.alloc(max_args * platmacro.SIZEOF_POINTER))
    if argv_arr == None:
        return

    argc: INT = 0
    i: t.CSizeT = 0
    j: t.CSizeT = 0
    in_quote: bool = False
    in_arg: bool = False

    while i < cmdlen:
        ch: t.CInt = cmdline[i]
        if ch == 34:  # 双引号
            in_quote = not in_quote
            if not in_arg:
                argv_arr[argc] = str(buf + j)
                argc += 1
                in_arg = True
        elif (ch == 32 or ch == 9) and not in_quote:
            # 空格或 Tab（引号外）：参数分隔符
            if in_arg:
                buf[j] = 0
                j += 1
                in_arg = False
        else:
            if not in_arg:
                argv_arr[argc] = str(buf + j)
                argc += 1
                in_arg = True
            buf[j] = ch
            j += 1
        i += 1

    if in_arg:
        buf[j] = 0

    _argc = argc
    _argv = argv_arr


def _init_argv_posix():
    """POSIX：读取 /proc/self/cmdline（参数以 \\0 分隔，末尾双 \\0）"""
    global _argc, _argv
    fd: INT = posix.open("/proc/self/cmdline", posix.O_RDONLY, 0)
    if fd < 0:
        return

    # 读取 cmdline（4KB 足够大多数情况）
    buf: bytes = _mbuddy.alloc(4096)
    if buf == None:
        posix.close(fd)
        return

    total: ssize_t = posix.read(fd, buf, 4096)
    posix.close(fd)
    if total <= 0:
        return

    # 计算参数个数（\0 分隔）
    argc: INT = 0
    i: t.CSizeT = 0
    total_size: t.CSizeT = t.CSizeT(total)
    while i < total_size:
        if buf[i] == 0:
            argc += 1
        i += 1

    if argc == 0:
        return

    # 分配指针数组
    argv_arr: str | t.CPtr = (str | t.CPtr)(_mbuddy.alloc(argc * platmacro.SIZEOF_POINTER))
    if argv_arr == None:
        return

    # 填充指针（每个参数的起始地址）
    argv_arr[0] = str(buf)
    idx: INT = 1
    i = 0
    while i < total_size and idx < argc:
        if buf[i] == 0:
            argv_arr[idx] = str(buf + i + 1)
            idx += 1
        i += 1

    _argc = argc
    _argv = argv_arr


def argc() -> int:
    """返回命令行参数个数。首次调用时自动初始化。"""
    if _argc == 0:
        _init_argv()
    return _argc


def argv(index: int) -> str:
    """返回第 index 个命令行参数（index 从 0 开始）。
    首次调用时自动初始化。索引越界返回 None。"""
    if _argc == 0:
        _init_argv()
    if index < 0 or index >= _argc:
        return None
    return _argv[index]
