package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strconv"
	"strings"
)

// Config 结构体存储配置信息
type Config struct {
	Global struct {
		LT map[string]string // 存储本地地址到目标地址的映射
		LU map[string]string // 存储本地地址到目标地址的映射
	}
}

// isValidHostname 验证主机名格式
func isValidHostname(hostname string) bool {
	if len(hostname) > 255 || hostname == "" {
		return false
	}
	for _, part := range strings.Split(hostname, ".") {
		if len(part) == 0 || len(part) > 63 {
			return false
		}
		for _, c := range part {
			if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-') {
				return false
			}
		}
	}
	return true
}

// parseAddress 解析并验证地址字符串
func parseAddress(address string) (string, int, error) {
	host, portStr, err := net.SplitHostPort(address)
	if err != nil {
		return "", 0, fmt.Errorf("地址格式错误: %s (格式应为 host:port)", address)
	}

	port, err := strconv.Atoi(portStr)
	if err != nil || port < 1 || port > 65535 {
		return "", 0, fmt.Errorf("无效的端口号: %s", address)
	}

	host = strings.Trim(host, "[]") // 去除 IPv6 方括号
	if net.ParseIP(host) == nil && !isValidHostname(host) {
		return "", 0, fmt.Errorf("无效的主机名或 IP: %s", address)
	}

	return host, port, nil
}

// parseConfig 解析配置文件
func parseConfig(filename string) (Config, error) {
	var config Config
	config.Global.LT = make(map[string]string)
	config.Global.LU = make(map[string]string)
	var currentSection string

	file, err := os.Open(filename)
	if err != nil {
		return config, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "#") {
			continue
		}

		if strings.HasSuffix(line, "{") {
			currentSection = strings.Fields(line)[0]
			continue
		}
		if line == "}" {
			currentSection = ""
			continue
		}

		parts := strings.SplitN(line, "=", 2)
		if len(parts) != 2 {
			continue
		}

		key := strings.TrimSpace(parts[0])
		value := strings.TrimSpace(strings.TrimSuffix(parts[1], ";"))

		if currentSection == "global" && key == "LT" {
			lsParts := strings.SplitN(value, "->", 2)
			if len(lsParts) == 2 {
				localAddr := strings.TrimSpace(lsParts[0])
				targetAddr := strings.TrimSpace(lsParts[1])

				if _, _, err := parseAddress(localAddr); err != nil {
					return config, fmt.Errorf("本地地址格式错误: %s", localAddr)
				}
				if _, _, err := parseAddress(targetAddr); err != nil {
					return config, fmt.Errorf("目标地址格式错误: %s", targetAddr)
				}

				config.Global.LT[localAddr] = targetAddr
			} else {
				return config, fmt.Errorf("LT 配置格式错误: %s", value)
			}
		}

		if currentSection == "global" && key == "LU" {
			lsParts := strings.SplitN(value, "->", 2)
			if len(lsParts) == 2 {
				localAddr := strings.TrimSpace(lsParts[0])
				targetAddr := strings.TrimSpace(lsParts[1])

				if _, _, err := parseAddress(localAddr); err != nil {
					return config, fmt.Errorf("本地地址格式错误: %s", localAddr)
				}
				if _, _, err := parseAddress(targetAddr); err != nil {
					return config, fmt.Errorf("目标地址格式错误: %s", targetAddr)
				}

				config.Global.LU[localAddr] = targetAddr
			} else {
				return config, fmt.Errorf("LU 配置格式错误: %s", value)
			}
		}
	}

	if err := scanner.Err(); err != nil {
		return config, err
	}

	return config, nil
}
