// Package main generated by 'freedom new-project investment'
package main

import (
	_ "investment/adapter/controller" //Implicit initialization controller
	_ "investment/adapter/repository" //Implicit initialization repository
	"investment/domain/po/custom"
	"investment/server/conf"
	"time"

	"github.com/8treenet/freedom"
	"github.com/8treenet/freedom/infra/requests"
	"github.com/8treenet/freedom/middleware"
	"github.com/go-redis/redis"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

//web服务

func main() {
	app := freedom.NewApplication()
	installDatabase(app)
	/*
		installDatabase(app)
		installRedis(app)

		HTTP/2 h2c Runner
		runner := app.NewH2CRunner(conf.Get().App.Other["listen_addr"].(string))
		HTTP/2 AutoTLS Runner
		runner := app.NewAutoTLSRunner(":443", "freedom.com www.freedom.com", "freedom@163.com")
		HTTP/2 TLS Runner
		runner := app.NewTLSRunner(":443", "certFile", "keyFile")
	*/
	installMiddleware(app)
	runner := app.NewRunner(conf.Get().App.Other["listen_addr"].(string))
	//app.InstallParty("/investment")
	liveness(app)
	app.Run(runner, conf.Get().App)
}

func installMiddleware(app freedom.Application) {
	app.InstallMiddleware(middleware.NewRecover())
	app.InstallMiddleware(middleware.NewTrace("x-request-id"))
	//One Loger per request New.
	app.InstallMiddleware(middleware.NewRequestLogger("x-request-id"))
	//The middleware output of the log line.
	app.Logger().Handle(middleware.DefaultLogRowHandle)

	//Install the Prometheus middleware.
	middle := middleware.NewClientPrometheus(conf.Get().App.Other["service_name"].(string), freedom.Prometheus())
	requests.InstallMiddleware(middle)

	//HTTP request link middleware that controls the header transmission of requests.
	app.InstallBusMiddleware(middleware.NewBusFilter())
}

func installDatabase(app freedom.Application) {
	app.InstallDB(func() any {
		conf := conf.Get().DB
		db, err := gorm.Open(sqlite.Open("investment.db"), &gorm.Config{})
		if err != nil {
			freedom.Logger().Fatal(err.Error())
		}
		db.AutoMigrate(&custom.ClsDepthArticle{})

		sqlDB, err := db.DB()
		if err != nil {
			freedom.Logger().Fatal(err)
		}
		if err = sqlDB.Ping(); err != nil {
			freedom.Logger().Fatal(err)
		}

		sqlDB.SetMaxIdleConns(conf.MaxIdleConns)
		sqlDB.SetMaxOpenConns(conf.MaxOpenConns)
		sqlDB.SetConnMaxLifetime(time.Duration(conf.ConnMaxLifeTime) * time.Second)
		return db
	})
}

func installRedis(app freedom.Application) {
	app.InstallRedis(func() (client redis.Cmdable) {
		cfg := conf.Get().Redis
		opt := &redis.Options{
			Addr:               cfg.Addr,
			Password:           cfg.Password,
			DB:                 cfg.DB,
			MaxRetries:         cfg.MaxRetries,
			PoolSize:           cfg.PoolSize,
			ReadTimeout:        time.Duration(cfg.ReadTimeout) * time.Second,
			WriteTimeout:       time.Duration(cfg.WriteTimeout) * time.Second,
			IdleTimeout:        time.Duration(cfg.IdleTimeout) * time.Second,
			IdleCheckFrequency: time.Duration(cfg.IdleCheckFrequency) * time.Second,
			MaxConnAge:         time.Duration(cfg.MaxConnAge) * time.Second,
			PoolTimeout:        time.Duration(cfg.PoolTimeout) * time.Second,
		}
		redisClient := redis.NewClient(opt)
		if e := redisClient.Ping().Err(); e != nil {
			freedom.Logger().Fatal(e.Error())
		}
		client = redisClient
		return
	})
}

func liveness(app freedom.Application) {
	app.Iris().Get("/ping", func(ctx freedom.Context) {
		ctx.WriteString("pong")
	})
}
