// DNS Server API
// @title DNS Server API
// @version 1.0
// @description DNS服务器API文档
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.email support@example.com
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost:8080
// @BasePath /api
package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"

	"dns-server/config"
	"dns-server/dns"
	"dns-server/gfw"
	"dns-server/http"
	"dns-server/logger"
	"dns-server/shield"
)

// createDefaultConfig 创建默认配置文件
func createDefaultConfig(configFile string) error {
	// 默认配置内容
	defaultConfig := `{
  "dns": {
    "port": 53,
    "upstreamDNS": [
      "223.5.5.5:53",
      "223.6.6.6:53"
    ],
    "dnssecUpstreamDNS": [
      "8.8.8.8:53",
      "1.1.1.1:53"
    ],
    "timeout": 5000,
    "saveInterval": 300,
    "cacheTTL": 30,
    "enableDNSSEC": true,
    "queryMode": "parallel"
  },
  "http": {
    "port": 8080,
    "host": "0.0.0.0",
    "enableAPI": true,
    "username": "admin",
    "password": "admin"
  },
  "shield": {
    "blacklists": [
      {
        "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
      }
    ],
    "updateInterval": 3600,
    "blockMethod": "NXDOMAIN",
    "customBlockIP": "",
    "statsSaveInterval": 60
  },
  "gfwList": {
    "ip": "127.0.0.1",
    "content": "./data/gfwlist.txt",
    "enabled": true
  },
  "log": {
    "level": "debug",
    "maxSize": 100,
    "maxBackups": 10,
    "maxAge": 30
  }
}`

	// 写入默认配置到文件
	return os.WriteFile(configFile, []byte(defaultConfig), 0644)
}

// createRequiredFiles 创建所需的文件和文件夹
func createRequiredFiles(cfg *config.Config) error {
	// 创建数据文件夹
	dataDir := "./data"
	if err := os.MkdirAll(dataDir, 0755); err != nil {
		return fmt.Errorf("创建数据文件夹失败: %w", err)
	}

	// 创建远程规则缓存文件夹
	if err := os.MkdirAll("data/remote_rules", 0755); err != nil {
		return fmt.Errorf("创建远程规则缓存文件夹失败: %w", err)
	}

	// 创建日志文件夹
	logDir := filepath.Dir("logs/dns-server.log")
	if logDir != "." {
		if err := os.MkdirAll(logDir, 0755); err != nil {
			return fmt.Errorf("创建日志文件夹失败: %w", err)
		}
	}

	// 创建自定义规则文件
	if _, err := os.Stat("data/rules.txt"); os.IsNotExist(err) {
		if err := os.WriteFile("data/rules.txt", []byte("# 自定义规则文件\n# 格式：域名\n# 例如：example.com\n"), 0644); err != nil {
			return fmt.Errorf("创建自定义规则文件失败: %w", err)
		}
	}

	// 创建Hosts文件
	if _, err := os.Stat("data/hosts.txt"); os.IsNotExist(err) {
		if err := os.WriteFile("data/hosts.txt", []byte("# Hosts文件\n# 格式：IP 域名\n# 例如：127.0.0.1 localhost\n"), 0644); err != nil {
			return fmt.Errorf("创建Hosts文件失败: %w", err)
		}
	}

	// 创建GFWList文件
	if _, err := os.Stat("data/gfwlist.txt"); os.IsNotExist(err) {
		if err := os.WriteFile("data/gfwlist.txt", []byte("# GFWList规则文件\n# 格式：每行一条规则\n# 例如：www.google.com\n"), 0644); err != nil {
			return fmt.Errorf("创建GFWList文件失败: %w", err)
		}
	}

	// 创建统计数据文件
	if _, err := os.Stat("data/stats.json"); os.IsNotExist(err) {
		if err := os.WriteFile("data/stats.json", []byte("{}"), 0644); err != nil {
			return fmt.Errorf("创建统计数据文件失败: %w", err)
		}
	}

	// 创建Shield统计数据文件
	if _, err := os.Stat("data/shield_stats.json"); os.IsNotExist(err) {
		if err := os.WriteFile("data/shield_stats.json", []byte("{}"), 0644); err != nil {
			return fmt.Errorf("创建Shield统计数据文件失败: %w", err)
		}
	}

	return nil
}

func main() {
	// 命令行参数解析
	var configFile string
	flag.StringVar(&configFile, "config", "config.json", "配置文件路径")
	flag.Parse()

	// 检查配置文件是否存在，如果不存在则创建默认配置文件
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		log.Printf("配置文件 %s 不存在，正在创建默认配置文件...", configFile)
		if err := createDefaultConfig(configFile); err != nil {
			log.Fatalf("创建默认配置文件失败: %v", err)
		}
		log.Printf("默认配置文件 %s 创建成功", configFile)
	}

	// 初始化配置
	var cfg *config.Config
	var err error
	cfg, err = config.LoadConfig(configFile)
	if err != nil {
		log.Fatalf("加载配置失败: %v", err)
	}

	// 创建所需的文件和文件夹
	log.Println("正在创建所需的文件和文件夹...")
	if err := createRequiredFiles(cfg); err != nil {
		log.Fatalf("创建所需文件和文件夹失败: %v", err)
	}
	log.Println("所需文件和文件夹创建成功")

	// 初始化日志系统
	if err := logger.InitLogger("logs/dns-server.log", cfg.Log.Level, 0, 0, 0, false); err != nil {
		log.Fatalf("初始化日志系统失败: %v", err)
	}
	defer logger.Close()

	// 初始化屏蔽管理系统
	shieldManager := shield.NewShieldManager(&cfg.Shield)
	if err := shieldManager.LoadRules(); err != nil {
		logger.Error("加载屏蔽规则失败", "error", err)
	}

	// 初始化GFWList管理系统
	gfwManager := gfw.NewGFWListManager(&cfg.GFWList)
	if err := gfwManager.LoadRules(); err != nil {
		logger.Error("加载GFWList规则失败", "error", err)
	}

	// 启动DNS服务器
	dnsServer := dns.NewServer(&cfg.DNS, &cfg.Shield, shieldManager, &cfg.GFWList, gfwManager)
	go func() {
		if err := dnsServer.Start(); err != nil {
			logger.Error("DNS服务器启动失败", "error", err)
			os.Exit(1)
		}
	}()

	// 启动HTTP控制台服务器
	httpServer := http.NewServer(cfg, dnsServer, shieldManager, gfwManager)
	go func() {
		if err := httpServer.Start(); err != nil {
			logger.Error("HTTP控制台服务器启动失败", "error", err)
		}
	}()

	// 启动定时更新任务
	go shieldManager.StartAutoUpdate()

	logger.Info(fmt.Sprintf("DNS服务器已启动，监听端口: %d", cfg.DNS.Port))
	logger.Info(fmt.Sprintf("HTTP控制台已启动，监听端口: %d", cfg.HTTP.Port))

	// 监听信号
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
	<-sigCh

	// 清理资源
	logger.Info("正在关闭服务...")
	dnsServer.Stop()
	httpServer.Stop()
	shieldManager.StopAutoUpdate()

	logger.Info("服务已关闭")
}
