package config

import (
	"fmt"
	"os"
	"regexp"

	"gopkg.in/yaml.v3"
)

// 域名匹配规则类型
const (
	MatchTypeRegexp  = "regexp"
	MatchTypeSuffix  = "suffix"
	MatchTypeKeyword = "keyword"
)

// DNS协议类型
const (
	DNSProtocolUDP = "udp"
	DNSProtocolTCP = "tcp"
	DNSProtocolDoT = "dot" // DNS over TLS
	DNSProtocolDoH = "doh" // DNS over HTTPS
	DNSProtocolDoQ = "doq" // DNS over QUIC
)

// 默认配置值
const (
	DefaultPort           = 443
	DefaultDNSProtocol    = DNSProtocolUDP
	DefaultDNSServer      = "8.8.8.8:53"
	DefaultDNSTimeout     = 5
	DefaultConnectTimeout = 10
	DefaultReadTimeout    = 30
	DefaultWriteTimeout   = 5
	DefaultIdleTimeout    = 60
	DefaultLifeTime       = 300
	DefaultLogLevel       = "info"
	DefaultMaxConns       = 1000
	DefaultMinFragSize    = 10
	DefaultMaxFragSize    = 100
	DefaultMinDelay       = 10
	DefaultMaxDelay       = 30
)

// 超时配置
type TimeoutConfig struct {
	Connect  int `yaml:"connect"`  // 连接超时（秒）
	Read     int `yaml:"read"`     // 读取超时（秒）
	Write    int `yaml:"write"`    // 写入超时（秒）
	Idle     int `yaml:"idle"`     // 空闲超时（秒）
	LifeTime int `yaml:"lifetime"` // 连接最大生命周期（秒）
}

// TLS分片配置
type FragmentConfig struct {
	Enabled  bool `yaml:"enabled"`   // 是否启用TLS分片
	MinSize  int  `yaml:"min_size"`  // 最小分片大小（字节）
	MaxSize  int  `yaml:"max_size"`  // 最大分片大小（字节）
	DelayMin int  `yaml:"delay_min"` // 分片之间的最小延迟（毫秒）
	DelayMax int  `yaml:"delay_max"` // 分片之间的最大延迟（毫秒）
	Validate bool `yaml:"validate"`  // 是否验证TLS记录完整性
}

// DNS解析器配置
type DNSResolverConfig struct {
	Protocol string `yaml:"protocol"` // udp, tcp, dot, doh, doq
	Server   string `yaml:"server"`   // 服务器地址，如 8.8.8.8:53, 1.1.1.1:853
	Timeout  int    `yaml:"timeout"`  // 超时时间（秒）
}

// 域名匹配规则
type DomainRule struct {
	Type  string `yaml:"type"`  // regexp, suffix, keyword
	Value string `yaml:"value"` // 匹配值

	// 编译后的正则表达式（仅当Type为regexp时使用）
	compiledRegexp *regexp.Regexp
}

// 代理规则
type ProxyRule struct {
	Domains  []DomainRule   `yaml:"domains"`
	Port     int            `yaml:"port"` // 目标端口，默认为443
	Fragment FragmentConfig `yaml:"fragment"`
}

// 配置结构
type Config struct {
	Listen      string            `yaml:"listen"`
	Rules       []ProxyRule       `yaml:"rules"`
	DefaultPort int               `yaml:"default_port"` // 默认目标端口，如果规则中未指定
	DNS         DNSResolverConfig `yaml:"dns"`          // DNS解析器配置
	Timeout     TimeoutConfig     `yaml:"timeout"`      // 超时配置
	LogLevel    string            `yaml:"log_level"`    // 日志级别：debug, info, warn, error
	MaxConns    int               `yaml:"max_conns"`    // 最大并发连接数
}

// 加载配置文件
func LoadConfig(path string) (*Config, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %w", err)
	}

	var cfg Config
	if err := yaml.Unmarshal(data, &cfg); err != nil {
		return nil, fmt.Errorf("解析配置文件失败: %w", err)
	}

	// 设置默认值
	setDefaultValues(&cfg)

	// 编译正则表达式
	if err := compileRegexps(&cfg); err != nil {
		return nil, err
	}

	return &cfg, nil
}

// 设置默认值
func setDefaultValues(cfg *Config) {
	// 设置默认端口
	if cfg.DefaultPort == 0 {
		cfg.DefaultPort = DefaultPort
	}

	// 设置默认DNS配置
	if cfg.DNS.Protocol == "" {
		cfg.DNS.Protocol = DefaultDNSProtocol
	}
	if cfg.DNS.Server == "" {
		cfg.DNS.Server = DefaultDNSServer
	}
	if cfg.DNS.Timeout == 0 {
		cfg.DNS.Timeout = DefaultDNSTimeout
	}

	// 设置默认超时配置
	if cfg.Timeout.Connect == 0 {
		cfg.Timeout.Connect = DefaultConnectTimeout
	}
	if cfg.Timeout.Read == 0 {
		cfg.Timeout.Read = DefaultReadTimeout
	}
	if cfg.Timeout.Write == 0 {
		cfg.Timeout.Write = DefaultWriteTimeout
	}
	if cfg.Timeout.Idle == 0 {
		cfg.Timeout.Idle = DefaultIdleTimeout
	}
	if cfg.Timeout.LifeTime == 0 {
		cfg.Timeout.LifeTime = DefaultLifeTime
	}

	// 设置默认日志级别
	if cfg.LogLevel == "" {
		cfg.LogLevel = DefaultLogLevel
	}

	// 设置默认最大连接数
	if cfg.MaxConns == 0 {
		cfg.MaxConns = DefaultMaxConns
	}

	// 设置规则默认值
	for i := range cfg.Rules {
		// 如果规则中未指定端口，使用默认端口
		if cfg.Rules[i].Port == 0 {
			cfg.Rules[i].Port = cfg.DefaultPort
		}

		// 设置TLS分片配置的默认值
		if cfg.Rules[i].Fragment.Enabled {
			setFragmentDefaults(&cfg.Rules[i].Fragment)
		}
	}
}

// 设置分片默认值
func setFragmentDefaults(frag *FragmentConfig) {
	// 设置默认的分片大小范围
	if frag.MinSize <= 0 {
		frag.MinSize = DefaultMinFragSize
	}
	if frag.MaxSize <= 0 {
		frag.MaxSize = DefaultMaxFragSize
	}
	if frag.MinSize > frag.MaxSize {
		frag.MinSize = frag.MaxSize
	}

	// 设置默认的分片延迟范围
	if frag.DelayMin <= 0 {
		frag.DelayMin = DefaultMinDelay
	}
	if frag.DelayMax <= 0 {
		frag.DelayMax = DefaultMaxDelay
	}
	if frag.DelayMin > frag.DelayMax {
		frag.DelayMin = frag.DelayMax
	}
}

// 编译正则表达式
func compileRegexps(cfg *Config) error {
	for i := range cfg.Rules {
		for j := range cfg.Rules[i].Domains {
			if cfg.Rules[i].Domains[j].Type == MatchTypeRegexp {
				re, err := regexp.Compile(cfg.Rules[i].Domains[j].Value)
				if err != nil {
					return fmt.Errorf("编译正则表达式失败 '%s': %w",
						cfg.Rules[i].Domains[j].Value, err)
				}
				cfg.Rules[i].Domains[j].compiledRegexp = re
			}
		}
	}
	return nil
}

// 检查域名是否匹配规则
func (r *DomainRule) Match(domain string) bool {
	switch r.Type {
	case MatchTypeRegexp:
		return r.compiledRegexp.MatchString(domain)
	case MatchTypeSuffix:
		return len(domain) >= len(r.Value) &&
			domain[len(domain)-len(r.Value):] == r.Value
	case MatchTypeKeyword:
		return contains(domain, r.Value)
	default:
		return false
	}
}

// 辅助函数：检查字符串是否包含子串
func contains(s, substr string) bool {
	for i := 0; i <= len(s)-len(substr); i++ {
		if s[i:i+len(substr)] == substr {
			return true
		}
	}
	return false
}
