/**
 * 设备信息服务 — TypeScript 实现
 *
 * 与 device_service.py 逻辑一致，保留原 Python 方法不变。
 * 提供带缓存的机器码、用户 IP、MAC 地址查询。
 *
 * 适用环境：Node.js / Electron
 */

import * as os from "node:os";
import * as dgram from "node:dgram";
import { DeviceFingerprint } from "./device";
import type { QueryMethod } from "./device";

// ============================================================
// 工具函数
// ============================================================

/** 对应 Python: _is_valid_ipv4(value) -> bool */
function isValidIPv4(value: string): boolean {
    const parts = value.split(".");
    if (parts.length !== 4) return false;
    for (const part of parts) {
        const num = parseInt(part, 10);
        if (isNaN(num) || num < 0 || num > 255) return false;
        if (part.length > 1 && part.startsWith("0")) return false;
    }
    // 排除环回地址和 0.0.0.0
    if (value.startsWith("127.") || value === "0.0.0.0") return false;
    return true;
}

/** 对应 Python: _resolve_user_ip() -> Optional[str] */
function resolveUserIp(): string | null {
    // 优先通过 UDP "伪连接" 获取本机出站 IP
    try {
        const sock = dgram.createSocket("udp4");
        // 同步方式不可行;使用 UDP connect + getsockname 的异步模式
        // 但在 Node.js 中这本质是同步的 (connect 不发送数据)
        sock.connect(80, "8.8.8.8");
        const address = sock.address();
        sock.close();
        if (address && typeof address.address === "string") {
            const ip = address.address;
            if (isValidIPv4(ip)) return ip;
        }
    } catch {
        // 忽略
    }

    // 回退: 遍历网络接口查找第一个有效的非环回 IPv4
    const interfaces = os.networkInterfaces();
    for (const ifaceList of Object.values(interfaces)) {
        if (!ifaceList) continue;
        for (const iface of ifaceList) {
            if (iface.family === "IPv4") {
                const ip = iface.address;
                if (isValidIPv4(ip)) return ip;
            }
        }
    }

    return null;
}

/** 对应 Python: _resolve_user_mac_address() -> Optional[str] */
function resolveUserMacAddress(): string | null {
    const interfaces = os.networkInterfaces();
    for (const ifaceList of Object.values(interfaces)) {
        if (!ifaceList) continue;
        for (const iface of ifaceList) {
            // 跳过环回接口
            if (iface.internal) continue;
            if (iface.mac && iface.mac !== "00:00:00:00:00:00") {
                // 对应 Python: 检查多播位
                const parts = iface.mac.split(":");
                if (parts.length === 6) {
                    const firstByte = parseInt(parts[0], 16);
                    // uuid.getnode 的多播位检查: (node >> 40) & 1
                    if ((firstByte & 1) === 0) {
                        return iface.mac.toUpperCase();
                    }
                }
            }
        }
    }
    return null;
}

// ============================================================
// 未解析标记
// ============================================================

const UNRESOLVED = Symbol("unresolved");

// ============================================================
// DeviceService 类
// ============================================================

export class DeviceService {
    private fingerprint = new DeviceFingerprint();

    private cachedMachineCode: string | null | typeof UNRESOLVED = UNRESOLVED;
    private cachedUserIp: string | null | typeof UNRESOLVED = UNRESOLVED;
    private cachedUserMacAddress: string | null | typeof UNRESOLVED = UNRESOLVED;

    private warmupStarted = false;

    /**
     * 获取机器码（带缓存）。
     * 对应 Python: get_machine_code() -> Optional[str]
     */
    getMachineCode(method: QueryMethod = "auto"): string | null {
        if (this.cachedMachineCode !== UNRESOLVED) {
            return this.cachedMachineCode;
        }

        const machineCode = this.fingerprint.getMachineCode(method);
        if (this.cachedMachineCode === UNRESOLVED) {
            this.cachedMachineCode = machineCode;
        }
        return machineCode;
    }

    /**
     * 获取用户本机 IP（带缓存）。
     * 对应 Python: get_user_ip() -> Optional[str]
     */
    getUserIp(): string | null {
        if (this.cachedUserIp !== UNRESOLVED) {
            return this.cachedUserIp;
        }

        const value = resolveUserIp();
        if (this.cachedUserIp === UNRESOLVED && value) {
            this.cachedUserIp = value;
        }
        return value;
    }

    /**
     * 获取用户 MAC 地址（带缓存）。
     * 对应 Python: get_user_mac_address() -> Optional[str]
     */
    getUserMacAddress(): string | null {
        if (this.cachedUserMacAddress !== UNRESOLVED) {
            return this.cachedUserMacAddress;
        }

        const value = resolveUserMacAddress();
        if (this.cachedUserMacAddress === UNRESOLVED) {
            this.cachedUserMacAddress = value;
        }
        return value;
    }

    /**
     * 异步预热机器码（后台线程）。
     * 对应 Python: warm_up_machine_code() -> None
     */
    warmUpMachineCode(): void {
        if (this.cachedMachineCode !== UNRESOLVED) return;
        if (this.warmupStarted) return;
        this.warmupStarted = true;

        // 使用 setImmediate 模拟后台线程，不阻塞当前事件循环
        setImmediate(() => {
            const machineCode = this.fingerprint.getMachineCode();
            if (this.cachedMachineCode === UNRESOLVED) {
                this.cachedMachineCode = machineCode;
            }
        });
    }
}

// ============================================================
// 便捷函数（单例）
// ============================================================

const defaultService = new DeviceService();

/** 获取机器码（单例，带缓存） */
export function getMachineCode(method: QueryMethod = "auto"): string | null {
    return defaultService.getMachineCode(method);
}

/** 获取用户本机 IP（单例，带缓存） */
export function getUserIp(): string | null {
    return defaultService.getUserIp();
}

/** 获取用户 MAC 地址（单例，带缓存） */
export function getUserMacAddress(): string | null {
    return defaultService.getUserMacAddress();
}

/** 异步预热机器码 */
export function warmUpMachineCode(): void {
    defaultService.warmUpMachineCode();
}
