package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"
)

// 主循环，为每个端口映射启动一个代理
func Loop(config Config) {
	ctx, cancel := context.WithCancel(context.Background())

	// 启动 TCP 代理
	for tcp_listenAddr, tcp_targetAddr := range config.Global.LT {
		tcpWg.Add(1)
		go StartTcpProxy(tcp_listenAddr, tcp_targetAddr)
	}

	// 启动 UDP 代理
	for udp_listenAddr, udp_targetAddr := range config.Global.LU {
		udpWg.Add(1)
		go StartUdpProxy(ctx, udp_listenAddr, udp_targetAddr)
	}

	// 监听退出信号，触发 `cancel()` 让所有 Goroutine 退出
	WaitForExit(cancel)
}

// 等待退出信号（如 Ctrl+C），并优雅地关闭所有代理服务
func WaitForExit(cancel context.CancelFunc) {
	sigChan := make(chan os.Signal, 1)
	// 注册接收 SIGINT、SIGTERM 信号
	signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

	<-sigChan // 阻塞直到收到退出信号
	fmt.Println("\n收到终止信号，准备关闭代理服务器...")

	// 关闭所有 TCP 监听器
	for _, listener := range tcp_listeners {
		if err := listener.Close(); err != nil {
			fmt.Printf("关闭 TCP 监听器 %s 失败: %v\n", listener.Addr(), err)
		}
	}

	// 通知 UDP goroutine 退出
	cancel()
	fmt.Println("[INFO] 已通知所有 goroutine 退出，等待清理...")

	// 等待所有 TCP 和 UDP goroutine 完成
	tcpWg.Wait()
	udpWg.Wait()

	fmt.Println("所有代理已安全退出")
	os.Exit(0)
}

func main() {
	daemon := flag.Bool("d", false, "守护进程模式")         // 解析命令行参数，是否以守护进程模式运行
	config := flag.String("c", "4to6.conf", "指定配置文件") // 解析命令行参数，是否以守护进程模式运行
	flag.Parse()

	if *daemon {
		Daemon() // 如果设置了-d参数，则进入守护进程模式
	}

	LT, err := parseConfig(*config)
	if err != nil {
		fmt.Fprintf(os.Stderr, "读取配置错误: %v\n", err)
		os.Exit(1)
	}

	Loop(LT) // 启动所有代理服务

}
