/*
 * network_info_demo.c — eduwin_net + eduwin_thread 网络功能演示
 *
 * ★ 重构后使用 eduwin_thread 模块替代手动 PostMessage + 子类化
 *   线程函数不再需要 DWORD WINAPI 签名，改为简单的 void func(void*)
 *   UI 更新通过 execute_on_main() 安全投递，无需自定义消息
 *
 * 编译：build.bat
 */

#define _CRT_SECURE_NO_WARNINGS
#include "eduwin.h"

/* ── 控件 ── */
static HWND g_win;
static HWND g_log;
static HWND g_status;
static HWND g_btn_ip, g_btn_dns, g_btn_tcp, g_btn_clear;

/* ── 日志辅助 ── */
static void llog(const WCHAR *s)
{
    const WCHAR *cur = get_text(g_log);
    if (!cur) cur = L"";
    int clen = (int)wcslen(cur);
    int slen = (int)wcslen(s);
    WCHAR *buf = (WCHAR*)malloc((clen + slen + 3) * sizeof(WCHAR));
    if (!buf) return;
    wcscpy(buf, cur);
    wcscat(buf, s);
    wcscat(buf, L"\r\n");
    set_text(g_log, buf);
    free(buf);
}

/* ── 在主线程执行的回调（eduwin_execute_on_main 的 targets） ── */
static void on_log(void *msg)
{
    llog((const WCHAR*)msg);
    free(msg);
}

static void on_status(void *msg)
{
    statusbar_set_text(g_status, (const WCHAR*)msg);
    free(msg);
}

/* ── 线程：获取公网 IP ── */
static void thread_fetch_ip(void *arg)
{
    (void)arg;

    execute_on_main(g_win, on_status, _wcsdup(L"正在获取公网 IP..."));

    http_t *resp = http_get("https://httpbin.org/ip");
    if (!resp)
    {
        WCHAR wbuf[256];
        swprintf(wbuf, 256, L"HTTP 请求失败: %S", net_error());
        execute_on_main(g_win, on_log, _wcsdup(wbuf));
    }
    else
    {
        int code = http_status(resp);
        const char *body = http_body(resp);
        WCHAR wbuf[1024];
        if (body && *body)
        {
            if (strstr(body, "\"origin\""))
                swprintf(wbuf, 1024, L"HTTP 公网 IP: %S (HTTP %d)", body, code);
            else
                swprintf(wbuf, 1024, L"HTTP 响应 (HTTP %d): %S", code, body);
        }
        else
        {
            swprintf(wbuf, 1024, L"HTTP 状态码: %d (无响应体)", code);
        }
        execute_on_main(g_win, on_log, _wcsdup(wbuf));
        http_free(resp);
    }

    execute_on_main(g_win, on_status, _wcsdup(L"就绪"));
}

/* ── 线程：DNS 解析 ── */
static void thread_dns_lookup(void *arg)
{
    const char *domain = (const char*)arg;
    execute_on_main(g_win, on_status, _wcsdup(L"正在解析域名..."));

    char ip[64] = {0};
    int r = dns_lookup(domain, ip, sizeof(ip));

    WCHAR wbuf[256];
    if (r == 0)
        swprintf(wbuf, 256, L"DNS %S → %S", domain, ip);
    else
        swprintf(wbuf, 256, L"DNS %S → 解析失败 (%S)", domain, net_error());
    execute_on_main(g_win, on_log, _wcsdup(wbuf));

    execute_on_main(g_win, on_status, _wcsdup(L"就绪"));
}

/* ── 线程：TCP 时间查询 ── */
static void thread_tcp_test(void *arg)
{
    (void)arg;
    execute_on_main(g_win, on_status, _wcsdup(L"正在连接 TCP 测试服务器..."));
    execute_on_main(g_win, on_log, _wcsdup(L"TCP 连接 time.nist.gov:13..."));

    tcp_t *conn = tcp_connect("time.nist.gov", 13);
    if (!conn)
    {
        WCHAR wbuf[256];
        swprintf(wbuf, 256, L"TCP 连接失败: %S", net_error());
        execute_on_main(g_win, on_log, _wcsdup(wbuf));
        execute_on_main(g_win, on_status, _wcsdup(L"就绪"));
        return;
    }

    execute_on_main(g_win, on_log, _wcsdup(L"TCP 连接成功，接收数据..."));
    char buf[1024] = {0};
    int r = tcp_recv_timeout(conn, buf, sizeof(buf) - 1, 5000);
    if (r > 0)
    {
        while (r > 0 && (buf[r-1] == '\n' || buf[r-1] == '\r')) buf[--r] = 0;
        WCHAR wbuf[2048];
        swprintf(wbuf, 2048, L"TCP 时间服务响应: %S", buf);
        execute_on_main(g_win, on_log, _wcsdup(wbuf));
    }
    else if (r == 0)
    {
        execute_on_main(g_win, on_log, _wcsdup(L"TCP 超时或无数据"));
    }
    else
    {
        WCHAR wbuf[256];
        swprintf(wbuf, 256, L"TCP 接收失败: %S", net_error());
        execute_on_main(g_win, on_log, _wcsdup(wbuf));
    }

    tcp_close(conn);
    execute_on_main(g_win, on_status, _wcsdup(L"就绪"));
}

/* ── 按钮回调 ── */
static void on_ip(void *data)
{
    (void)data;
    thread_run(thread_fetch_ip, NULL);
}

static void on_dns(void *data)
{
    (void)data;
    thread_run(thread_dns_lookup, _strdup("www.xtu.edu.cn"));
}

static void on_tcp(void *data)
{
    (void)data;
    thread_run(thread_tcp_test, NULL);
}

static void on_clear(void *data)
{
    (void)data;
    set_text(g_log, L"");
}

/* ── 入口 ── */
int main(void)
{
    /* 初始化网络模块 */
    if (net_init() != 0)
    {
        alert(L"错误", L"网络模块初始化失败");
        return 1;
    }

    /* 初始化 Eduwin */
    if (init_app() != 0)
    {
        alert(L"错误", L"Eduwin 初始化失败");
        net_cleanup();
        return 1;
    }

    /* 初始化线程模块（需在 init_app 之后） */
    if (thread_init() != 0)
    {
        alert(L"错误", L"线程模块初始化失败");
        net_cleanup();
        return 1;
    }

    g_win = create_window(L"网络模块功能演示 (eduwin_net)", 620, 480);
    if (!g_win)
    {
        alert(L"错误", L"创建窗口失败");
        thread_cleanup();
        net_cleanup();
        return 1;
    }

    int m = 8;
    int cw = 620 - 2 * m;

    /* 日志文本框 */
    g_log = create_textarea(g_win, L"", m, m, cw, 280);
    set_readonly(g_log, 1);

    /* 按钮行 */
    int by = m + 280 + m;
    g_btn_ip    = create_button(g_win, L"获取公网 IP",   m,        by, 120, 32);
    g_btn_dns   = create_button(g_win, L"DNS 解析域名",  m+128,    by, 120, 32);
    g_btn_tcp   = create_button(g_win, L"TCP 时间查询",  m+256,    by, 120, 32);
    g_btn_clear = create_button(g_win, L"清空",           m+384,    by, 60,  32);

    on_button_click(g_btn_ip,    on_ip,    NULL);
    on_button_click(g_btn_dns,   on_dns,   NULL);
    on_button_click(g_btn_tcp,   on_tcp,   NULL);
    on_button_click(g_btn_clear, on_clear, NULL);

    /* 状态栏 */
    g_status = create_statusbar(g_win);
    statusbar_set_text(g_status, L"就绪");

    show_window(g_win);

    /* 启动信息 */
    llog(L"═════ Network Info Demo ═════");
    llog(L"eduwin_net + eduwin_thread 演示");
    llog(L"★ 已重构：使用 execute_on_main() 替代 PostMessage + 子类化");
    llog(L"");

    run_app();

    thread_cleanup();
    net_cleanup();
    return 0;
}
