# -*- coding: utf-8 -*-
"""tcp_debug_tool.py 扩展冒烟测试:基础收发 + 统计/历史/循环发送/文件/导出/踢线/自动重连/在线时长/窗口记忆。"""
import json
import os
import tempfile
import time
import tkinter as tk

import tcp_debug_tool as t

# ---------- 1. 工具函数 ----------
assert t.encode_text("你好", "GBK", False) == "你好".encode("gbk")
assert t.encode_text("01 0A ff", "UTF-8", True) == bytes([0x01, 0x0A, 0xFF])
assert t.decode_bytes(b"\xc4\xe3\xba\xc3", "GBK", False) == "你好"
assert t.decode_bytes(bytes([0x01, 0x0A]), "UTF-8", True) == "01 0A"
assert t.fmt_duration(3661) == "01:01:01"
print("PASS 1: 工具函数")

# ---------- 2. GUI 集成 ----------
root = tk.Tk()
root.withdraw()
server = t.ServerTab(root)
client = t.ClientTab(root)
PORT = 19088


def pump(seconds):
    end = time.time() + seconds
    while time.time() < end:
        root.update()
        time.sleep(0.02)


# 启动服务端并连接客户端
server.var_port.set(str(PORT))
server.toggle_server()
pump(0.3)
client.var_host.set("127.0.0.1")
client.var_port.set(str(PORT))
client.toggle_connect()
pump(1.0)
assert client.sock is not None, "客户端连接失败"
assert server.srv_state.get().startswith("监听中"), server.srv_state.get()
print("PASS 2: 服务端启动 + 客户端连接")

# 在线时长显示
server._refresh_client_list()
assert "在线" in server.client_listbox.get(0), server.client_listbox.get(0)
print("PASS 3: 客户端列表显示在线时长")

# 客户端 GBK 发送 -> 服务端 GBK 接收
server.var_encoding.set("GBK")
client.var_encoding.set("GBK")
client.send_text.insert("1.0", "你好服务器")
client.do_send()
pump(0.6)
slog = server.log_text.get("1.0", "end")
assert "你好服务器" in slog, "服务端未收到中文: " + slog
print("PASS 4: 客户端 GBK 发送 -> 服务端 GBK 接收")

# 服务端 HEX 发送 -> 客户端 HEX 视图接收
client.var_hex_view.set(True)
server.var_hex_send.set(True)
server.send_text.insert("1.0", "AB CD 12 34")
server.client_listbox.selection_set(0)
server.do_send()
pump(0.6)
clog = client.log_text.get("1.0", "end")
assert "AB CD 12 34" in clog, "客户端未收到 HEX: " + clog
print("PASS 5: 服务端 HEX 发送 -> 客户端 HEX 显示")

# 收发统计
assert client._stats["tx_msgs"] == 1 and client._stats["rx_msgs"] == 1, client._stats
assert server._stats["tx_msgs"] == 1 and server._stats["rx_msgs"] == 1, server._stats
assert client._stats["tx_bytes"] == len("你好服务器".encode("gbk")), client._stats
client._refresh_stats_label()
assert "发送 1 条" in client.stats_label.cget("text"), client.stats_label.cget("text")
print("PASS 6: 收发统计")

# 广播 + 历史报文记录
client.var_hex_view.set(False)
server.var_hex_send.set(False)
server.send_text.delete("1.0", "end")
server.send_text.insert("1.0", "hello from server")
server.do_broadcast()
pump(0.6)
clog = client.log_text.get("1.0", "end")
assert "hello from server" in clog, "客户端未收到广播: " + clog
assert client._history and client._history[-1] == "你好服务器", client._history
client._nav_history(-1)
assert "你好服务器" in client.send_text.get("1.0", "end"), "历史切换失败"
print("PASS 7: 广播 + 历史报文记录/切换")

# 定时循环发送(3 次)
client.send_text.delete("1.0", "end")
client.send_text.insert("1.0", "loop-msg")
client.var_loop_interval.set("0.05")
client.var_loop_count.set("3")
client._loop_toggle()
pump(1.0)
assert client._loop_running is False, "循环发送未自动停止"
slog = server.log_text.get("1.0", "end")
assert slog.count("loop-msg") == 3, "循环发送次数不符: " + slog
print("PASS 8: 定时循环发送(3 次自动停止)")

# 发送文件(原样字节)
tmp_send = os.path.join(tempfile.gettempdir(), "tcp_tool_send_test.bin")
with open(tmp_send, "wb") as f:
    f.write(b"\x01\x02\x03TEST")
data = client._read_file_bytes(tmp_send)
assert data == b"\x01\x02\x03TEST", "读取文件失败"
client._send_raw(data, "文件测试")
pump(0.6)
slog = server.log_text.get("1.0", "end")
assert "TEST" in slog, "服务端未收到文件内容: " + slog
print("PASS 9: 发送文件(原样字节)")

# 导出记录
tmp_log = os.path.join(tempfile.gettempdir(), "tcp_tool_export_test.txt")
client._write_log_to(tmp_log)
with open(tmp_log, encoding="utf-8") as f:
    exported = f.read()
assert "你好服务器" in exported and "hello from server" in exported, exported[:200]
print("PASS 10: 导出收发记录")

# 服务端断开所选客户端
server.client_listbox.selection_set(0)
server._kick_selected()
pump(0.6)
assert client.sock is None, "踢线后客户端未断开"
assert client.conn_state.get() == "未连接", client.conn_state.get()
print("PASS 11: 服务端断开所选客户端")

# 自动重连:停止服务 -> 断线 -> 重启服务 -> 自动连上
client.var_autoreconnect.set(True)
client.var_reconnect_interval.set("0.5")
client.toggle_connect()          # 手动重新连上
pump(1.0)
assert client.sock is not None, "重新连接失败"
server._stop_server()            # 服务端下线,客户端断线触发自动重连
pump(0.8)
assert client.conn_state.get().startswith("未连接"), client.conn_state.get()
server.toggle_server()           # 服务端恢复
pump(3.0)
assert client.sock is not None, "自动重连失败"
assert client.conn_state.get().startswith("已连接"), client.conn_state.get()
client._disconnect()
print("PASS 12: 自动重连")

# 清理标签页测试环境(先 shutdown 取消周期回调,再销毁)
client.shutdown()
server.shutdown()
pump(0.2)
root.destroy()
print("PASS 13: 断开连接 / 停止服务")

# ---------- 3. 窗口大小记忆 ----------
cfg_path = t.CONFIG_FILE
with open(cfg_path, "w", encoding="utf-8") as f:
    json.dump({"geometry": "900x600"}, f)
app = t.App()
app.update()   # 映射窗口后 geometry() 才返回实际尺寸
assert "900x600" in app.geometry(), app.geometry()
app._on_close()   # 保存并销毁
assert os.path.exists(cfg_path)
with open(cfg_path, encoding="utf-8") as f:
    assert json.load(f).get("geometry"), "窗口大小未保存"
os.remove(cfg_path)
print("PASS 14: 窗口大小记忆")
print("ALL TESTS PASSED")