package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"net/http"
	"os"
	"strconv"
	"strings"

	"ems.agt/features/dbrest"
	"ems.agt/features/fm"
	"ems.agt/features/lm"
	"ems.agt/features/pm"
	"ems.agt/lib/dborm"
	"ems.agt/lib/global"
	"ems.agt/lib/log"
	"ems.agt/lib/routes"
	"ems.agt/restagent/config"
	"ems.agt/src"
	libSession "ems.agt/src/lib_features/session"
	"github.com/gin-gonic/gin"
)

// const defaultConfigFile = "./etc/restconf.yaml"

// func init() {
// 	cfile := flag.String("c", defaultConfigFile, "config file")
// 	pv := flag.Bool("v", false, "print version")
// 	ph := flag.Bool("h", false, "print help")

// 	flag.Parse()
// 	if *pv {
// 		fmt.Printf("OMC restagent version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer)
// 		os.Exit(0)
// 	}
// 	if *ph {
// 		flag.Usage()
// 		os.Exit(0)
// 	}

// 	config.ReadConfig(*cfile)
// 	config.UriPrefix = config.GetYamlConfig().OMC.UriPrefix
// 	//fmt.Println(config.UriPrefix)
// }

// func listenIPv6(ipv6 string, port int) {
// 	//
// 	addr := &net.TCPAddr{
// 		IP:   net.ParseIP(ipv6),
// 		Port: port,
// 	}

// 	listener, err := net.ListenTCP("tcp6", addr)
// 	if err != nil {
// 		fmt.Println("Failed to listen:", err)
// 		return
// 	}

// 	server := &http.Server{}
// 	err = server.Serve(listener)
// 	if err != nil {
// 		fmt.Println("Failed to serve:", err)
// 	}
// }

func HttpListen(addr string, router http.Handler) {
	err := http.ListenAndServe(addr, router)
	if err != nil {
		fmt.Println("ListenAndServe err:", err)
		os.Exit(5)
	}
}

func HttpListenTLS(addr, certFile, keyFile string, router http.Handler) {
	err := http.ListenAndServeTLS(addr, certFile, keyFile, router)
	if err != nil {
		fmt.Println("ListenAndServeTLS err:", err)
		os.Exit(6)
	}
}

func HttpListenConfigTLS(addr, caFile, certFile, keyFile string, router http.Handler) {
	// 加载根证书
	caCert, err := os.ReadFile(caFile)
	if err != nil {
		log.Fatal(err)
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)

	// 创建自定义的TLS配置
	tlsConfig := &tls.Config{
		ClientCAs:  caCertPool,
		ClientAuth: tls.RequireAndVerifyClientCert,
	}

	// 创建HTTP服务器
	server := &http.Server{
		Addr:      addr,
		Handler:   router,
		TLSConfig: tlsConfig,
	}

	err = server.ListenAndServeTLS(certFile, keyFile)
	if err != nil {
		fmt.Println("ListenAndServeTLS err:", err)
		os.Exit(6)
	}
}

func HttpListenWebServerTLS(addr, certFile, keyFile string) {
	err := http.ListenAndServeTLS(addr, certFile, keyFile, nil)
	if err != nil {
		fmt.Println("ListenAndServeTLS err:", err)
		os.Exit(7)
	}
}

func HttpListenWebServer(addr string) {
	err := http.ListenAndServe(addr, nil)
	if err != nil {
		fmt.Println("ListenAndServe err:", err)
		os.Exit(7)
	}
}

func main() {
	// src 配置中心初始加载
	src.ConfigurationInit()
	app := src.AppEngine()

	conf := config.GetYamlConfig()

	log.InitLogger(conf.Logger.File, conf.Logger.Duration, conf.Logger.Count, "omc:restagent", config.GetLogLevel())
	fmt.Printf("OMC restagent version: %s\n", global.Version)
	log.Infof("========================= OMC restagent startup =========================")
	log.Infof("OMC restagent version: %s %s %s", global.Version, global.BuildTime, global.GoVer)

	err := dborm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
		conf.Database.Host, conf.Database.Port, conf.Database.Name)
	if err != nil {
		fmt.Println("dborm.initDbClient err:", err)
		os.Exit(4)
	}
	err = fm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
		conf.Database.Host, conf.Database.Port, conf.Database.Name)
	if err != nil {
		fmt.Println("dborm.initDbClient err:", err)
		os.Exit(4)
	}
	err = pm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
		conf.Database.Host, conf.Database.Port, conf.Database.Name)
	if err != nil {
		fmt.Println("dborm.initDbClient err:", err)
		os.Exit(4)
	}
	err = dbrest.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
		conf.Database.Host, conf.Database.Port, conf.Database.Name)
	if err != nil {
		fmt.Println("rests.initDbClient err:", err)
		os.Exit(4)
	}
	err = lm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password,
		conf.Database.Host, conf.Database.Port, conf.Database.Name)
	if err != nil {
		fmt.Println("lm.initDbClient err:", err)
		os.Exit(4)
	}

	// 将 mux.Router 注册到 gin.Engine

	// 默认路由组
	defaultUriGroup := app.Group(config.DefaultUriPrefix)
	defaultUriGroup.Use(libSession.SessionHeader())
	defaultUriGroup.Any("/*any", gin.WrapH(routes.NewRouter()))
	// 可配置前缀路由组
	uriGroup := app.Group(config.UriPrefix)
	uriGroup.Use(libSession.SessionHeader())
	uriGroup.Any("/*any", gin.WrapH(routes.NewRouter()))

	// 开启监控采集
	// monitor.StartMonitor(false, "")

	for _, rest := range conf.Rest {
		// ipv4 goroutines
		if rest.IPv4 != "" {
			listen := rest.IPv4 + ":" + strconv.Itoa(int(rest.Port))
			if strings.ToLower(rest.Scheme) == "https" {
				go HttpListenTLS(listen, rest.CertFile, rest.KeyFile, app)
			} else {
				go HttpListen(listen, app)
			}

		}
		// ipv6 goroutines
		if rest.IPv6 != "" {
			listenv6 := "[" + rest.IPv6 + "]" + ":" + strconv.Itoa(int(rest.Port))
			if strings.ToLower(rest.Scheme) == "https" {
				go HttpListenTLS(listenv6, rest.CertFile, rest.KeyFile, app)
			} else {
				go HttpListen(listenv6, app)
			}
		}
	}

	if conf.WebServer.Enabled {
		fs := http.FileServer(http.Dir(conf.WebServer.RootDir))
		http.Handle("/", fs)
		for _, listen := range conf.WebServer.Listen {
			if strings.ToLower(listen.Scheme) == "https" {
				go HttpListenWebServerTLS(listen.Addr, listen.CertFile, listen.KeyFile)
			} else {
				go HttpListenWebServer(listen.Addr)
			}
		}
	}

	select {}
}
