package config

import (
	"encoding/json"
	"io/ioutil"
)

// DomainSpecificDNS 域名特定DNS服务器配置
// 格式：{"domainMatch": ["dns1", "dns2"]}
// domainMatch: 域名匹配字符串，当域名中包含该字符串时使用对应的DNS服务器
// dns1, dns2: 用于解析匹配域名的DNS服务器列表

type DomainSpecificDNS map[string][]string

// DNSConfig DNS配置
type DNSConfig struct {
	Port              int               `json:"port"`
	UpstreamDNS       []string          `json:"upstreamDNS"`
	DNSSECUpstreamDNS []string          `json:"dnssecUpstreamDNS"` // 用于DNSSEC查询的专用服务器
	SaveInterval      int               `json:"saveInterval"`      // 数据保存间隔（秒）
	CacheTTL          int               `json:"cacheTTL"`          // DNS缓存过期时间（分钟）
	EnableDNSSEC      bool              `json:"enableDNSSEC"`      // 是否启用DNSSEC支持
	QueryMode         string            `json:"queryMode"`         // 查询模式："parallel"（并行请求）、"fastest-ip"（最快的IP地址）
	QueryTimeout      int               `json:"queryTimeout"`      // 查询超时时间（毫秒）
	EnableFastReturn  bool              `json:"enableFastReturn"`  // 是否启用快速返回机制
	DomainSpecificDNS DomainSpecificDNS `json:"domainSpecificDNS"` // 域名特定DNS服务器配置
	NoDNSSECDomains   []string          `json:"noDNSSECDomains"`   // 不验证DNSSEC的域名模式列表
	EnableIPv6        bool              `json:"enableIPv6"`        // 是否启用IPv6解析（AAAA记录）
	CacheMode         string            `json:"cacheMode"`         // 缓存模式："memory"（内存缓存）、"file"（文件缓存）
	CacheSize         int               `json:"cacheSize"`         // 缓存大小限制（MB），0表示不缓存
	MaxCacheTTL       int               `json:"maxCacheTTL"`       // 最大缓存TTL（分钟）
	MinCacheTTL       int               `json:"minCacheTTL"`       // 最小缓存TTL（分钟）
	CacheFilePath     string            `json:"cacheFilePath"`     // 缓存文件路径
}

// HTTPConfig HTTP控制台配置
type HTTPConfig struct {
	Port      int    `json:"port"`
	Host      string `json:"host"`
	EnableAPI bool   `json:"enableAPI"`
	Username  string `json:"username"` // 登录用户名
	Password  string `json:"password"` // 登录密码
}

// BlacklistEntry 黑名单条目
type BlacklistEntry struct {
	Name           string `json:"name"`
	URL            string `json:"url"`
	Enabled        bool   `json:"enabled"`
	RuleCount      int    `json:"ruleCount,omitempty"`
	LastUpdateTime string `json:"lastUpdateTime,omitempty"`
}

// ShieldConfig 屏蔽规则配置
type ShieldConfig struct {
	Blacklists        []BlacklistEntry `json:"blacklists"`
	UpdateInterval    int              `json:"updateInterval"`
	BlockMethod       string           `json:"blockMethod"`       // 屏蔽方法: "NXDOMAIN", "refused", "emptyIP", "customIP"
	CustomBlockIP     string           `json:"customBlockIP"`     // 自定义屏蔽IP，当BlockMethod为"customIP"时使用
	StatsSaveInterval int              `json:"statsSaveInterval"` // 计数数据保存间隔（秒）
}

// GFWListConfig GFWList配置
type GFWListConfig struct {
	IP      string `json:"ip"`      // GFWList域名解析的目标IP地址
	Content string `json:"content"` // GFWList规则文件路径
	Enabled bool   `json:"enabled"` // 是否启用GFWList功能
}

// LogConfig 日志配置
type LogConfig struct {
	Level      string `json:"level"`
	MaxSize    int    `json:"maxSize"`
	MaxBackups int    `json:"maxBackups"`
	MaxAge     int    `json:"maxAge"`
}

// Config 整体配置
type Config struct {
	DNS     DNSConfig     `json:"dns"`
	HTTP    HTTPConfig    `json:"http"`
	Shield  ShieldConfig  `json:"shield"`
	GFWList GFWListConfig `json:"gfwList"` // GFWList配置
	Log     LogConfig     `json:"log"`
}

// LoadConfig 加载配置文件
func LoadConfig(path string) (*Config, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}

	var config Config
	err = json.Unmarshal(data, &config)
	if err != nil {
		return nil, err
	}

	// 设置默认值
	if config.DNS.Port == 0 {
		config.DNS.Port = 53
	}
	if len(config.DNS.UpstreamDNS) == 0 {
		config.DNS.UpstreamDNS = []string{"223.5.5.5:53", "223.6.6.6:53"}
	}
	if config.DNS.SaveInterval == 0 {
		config.DNS.SaveInterval = 300 // 默认5分钟保存一次
	}
	// 默认DNS缓存TTL为30分钟
	if config.DNS.CacheTTL == 0 {
		config.DNS.CacheTTL = 30 // 默认30分钟
	}
	// 缓存模式默认值
	if config.DNS.CacheMode == "" {
		config.DNS.CacheMode = "memory" // 默认内存缓存
	}
	// 缓存大小默认值（100MB）
	if config.DNS.CacheSize == 0 {
		config.DNS.CacheSize = 100 // 默认100MB
	}
	// 最大缓存TTL默认值（120分钟）
	if config.DNS.MaxCacheTTL == 0 {
		config.DNS.MaxCacheTTL = 120 // 默认120分钟
	}
	// 最小缓存TTL默认值（5分钟）
	if config.DNS.MinCacheTTL == 0 {
		config.DNS.MinCacheTTL = 5 // 默认5分钟
	}
	// 缓存文件路径固定为data/cache.json，不再从配置文件读取
	config.DNS.CacheFilePath = "data/cache.json"
	// DNSSEC默认配置
	// 如果未在配置文件中设置，默认启用DNSSEC支持
	// json.Unmarshal会将未设置的布尔字段设为false，所以我们需要显式检查
	// 但由于这是一个新字段，为了向后兼容，我们保持默认值为true
	// 注意：如果用户在配置文件中明确设置为false，则使用false
	if !config.DNS.EnableDNSSEC {
		// 检查是否真的是用户设置为false，还是默认值
		// 由于JSON布尔值默认是false，我们无法直接区分
		// 所以这里保持默认行为，让用户可以通过配置文件设置为false
	}
	// IPv6默认配置
	// 注意：我们不能直接设置默认值，因为JSON布尔值默认是false
	// 我们需要检查配置文件中是否真的设置了这个字段
	// 由于我们无法直接区分，这里保持现状，让用户可以通过配置文件设置为false
	// DNSSEC专用服务器默认配置
	if len(config.DNS.DNSSECUpstreamDNS) == 0 {
		config.DNS.DNSSECUpstreamDNS = []string{"8.8.8.8:53", "1.1.1.1:53"}
	}
	// 查询模式默认配置
	if config.DNS.QueryMode == "" {
		config.DNS.QueryMode = "parallel" // 默认使用并行请求模式
	}
	// 查询超时默认配置（毫秒）
	if config.DNS.QueryTimeout == 0 {
		config.DNS.QueryTimeout = 500 // 默认超时时间为500ms
	}
	// 快速返回机制默认配置
	if config.DNS.EnableFastReturn == false {
		config.DNS.EnableFastReturn = true // 默认启用快速返回机制
	}
	// 域名特定DNS服务器配置默认值
	if config.DNS.DomainSpecificDNS == nil {
		config.DNS.DomainSpecificDNS = make(DomainSpecificDNS) // 默认为空映射
	}

	if config.HTTP.Port == 0 {
		config.HTTP.Port = 8080
	}
	if config.HTTP.Host == "" {
		config.HTTP.Host = "0.0.0.0"
	}
	// 默认用户名和密码，如果未配置则使用admin/admin
	if config.HTTP.Username == "" {
		config.HTTP.Username = "admin"
	}
	if config.HTTP.Password == "" {
		config.HTTP.Password = "admin"
	}
	if config.Shield.UpdateInterval == 0 {
		config.Shield.UpdateInterval = 3600
	}
	if config.Shield.BlockMethod == "" {
		config.Shield.BlockMethod = "NXDOMAIN" // 默认屏蔽方法为NXDOMAIN
	}
	if config.Shield.StatsSaveInterval == 0 {
		config.Shield.StatsSaveInterval = 300 // 默认5分钟保存一次
	}

	// GFWList默认配置
	if config.GFWList.IP == "" {
		config.GFWList.IP = "127.0.0.1" // 默认GFWList解析目标IP为127.0.0.1
	}
	// GFWList默认启用（仅当未在配置文件中明确设置为false时）
	// 注意：如果用户在配置文件中明确设置为false，则保持为false

	// 如果黑名单列表为空，添加一些默认的黑名单
	if len(config.Shield.Blacklists) == 0 {
		config.Shield.Blacklists = []BlacklistEntry{
			{Name: "AdGuard DNS filter", URL: "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/filter.txt", Enabled: true},
			{Name: "Adaway Default Blocklist", URL: "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/hosts/adaway.txt", Enabled: true},
			{Name: "CHN-anti-AD", URL: "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-Filters/raw/branch/main/list/easylist.txt", Enabled: true},
			{Name: "My GitHub Rules", URL: "https://gitea.amazehome.xyz/AMAZEHOME/hosts-and-filters/raw/branch/main/rules/costomize.txt", Enabled: true},
		}
	}
	if config.Log.Level == "" {
		config.Log.Level = "info"
	}

	return &config, nil
}
