package src

import (
	"embed"
	"fmt"

	"be.ems/src/framework/config"
	"be.ems/src/framework/errorcatch"
	"be.ems/src/framework/middleware"
	"be.ems/src/framework/middleware/security"
	"be.ems/src/modules/chart"
	"be.ems/src/modules/common"
	"be.ems/src/modules/crontask"
	"be.ems/src/modules/monitor"
	networkdata "be.ems/src/modules/network_data"
	networkelement "be.ems/src/modules/network_element"
	"be.ems/src/modules/system"
	"be.ems/src/modules/trace"
	"be.ems/src/modules/ws"

	"github.com/gin-gonic/gin"
)

//go:embed assets/*
var assetsDir embed.FS

// 路由函数句柄，交给由 http.ListenAndServe(addr, router)
func AppEngine() *gin.Engine {
	app := initAppEngine()

	// 初始全局默认
	initDefeat(app)

	// 初始模块路由
	initModulesRoute(app)

	// 设置程序内全局资源访问
	config.SetAssetsDirFS(assetsDir)

	// 读取服务配置
	app.ForwardedByClientIP = config.Get("server.proxy").(bool)
	return app
}

// 运行服务程序 main.go
//
//	func main() {
//		src.ConfigurationInit()
//		if err := src.RunServer(); err != nil {
//			src.ConfigurationClose()
//		}
//	}
func RunServer() error {
	app := AppEngine()

	// 读取服务配置
	app.ForwardedByClientIP = config.Get("server.proxy").(bool)
	addr := fmt.Sprintf(":%d", config.Get("server.port").(int))

	// 启动服务
	fmt.Printf("\nopen http://localhost%s \n\n", addr)
	return app.Run(addr)
}

// 初始应用引擎
func initAppEngine() *gin.Engine {
	var app *gin.Engine

	// 禁止控制台日志输出的颜色
	gin.DisableConsoleColor()

	// 根据运行环境注册引擎
	if config.Env() == "prod" {
		gin.SetMode(gin.ReleaseMode)
		app = gin.New()
		app.Use(gin.Recovery())
	} else {
		app = gin.Default()
	}

	return app
}

// 初始全局默认
func initDefeat(app *gin.Engine) {
	// 全局中间件
	app.Use(errorcatch.ErrorCatch(), middleware.Report(), middleware.Cors(), security.Security())

	// 静态目录-静态资源
	if v := config.Get("staticFile.default"); v != nil {
		fsMap := v.(map[string]any)
		prefix, dir := fsMap["prefix"], fsMap["dir"]
		if prefix != nil && dir != nil {
			app.StaticFS(prefix.(string), gin.Dir(dir.(string), true))
		}
	}

	// 静态目录-上传资源
	if v := config.Get("staticFile.upload"); v != nil {
		fsMap := v.(map[string]any)
		prefix, dir := fsMap["prefix"], fsMap["dir"]
		if prefix != nil && dir != nil {
			app.StaticFS(prefix.(string), gin.Dir(dir.(string), true))
		}
	}

	// 路由未找到时
	app.NoRoute(func(c *gin.Context) {
		c.JSON(404, gin.H{
			"code": 404,
			"msg":  fmt.Sprintf("%s Not Found", c.Request.RequestURI),
		})
	})
}

// 初始模块路由
func initModulesRoute(app *gin.Engine) {
	// 通用模块
	common.Setup(app)
	// 系统模块
	system.Setup(app)
	// 网元功能模块
	networkelement.Setup(app)
	// 网元数据模块
	networkdata.Setup(app)
	// 跟踪模块
	trace.Setup(app)
	// 图表模块
	chart.Setup(app)
	// ws 模块
	ws.Setup(app)
	// 调度任务模块--暂无接口
	crontask.Setup(app)
	// 监控模块 - 含调度处理加入队列，放最后
	monitor.Setup(app)
}
