package model

import (
	"log"
	"sync"

	"github.com/pingcap/jira-bot/pkg/util"

	"github.com/pingcap/jira-bot/pkg/job"

	larkConf "github.com/larksuite/oapi-sdk-go/core/config"
	"github.com/pingcap/jira-bot/pkg/config"

	"github.com/larksuite/oapi-sdk-go/core"

	"github.com/pingcap/jira-bot/pkg/db"

	v3 "github.com/larksuite/oapi-sdk-go/service/contact/v3"
	"gorm.io/gorm"
)

type App struct {
	LarkConf           *larkConf.Config
	LarkContactService *v3.Service
	*gorm.DB
	NotificationRules
	AcFilter util.IAccessControl
	ShutDown func()
}

var app *App
var once sync.Once
var err error

func InitApp() error {
	once.Do(func() {
		app = &App{}
		appSettings := core.NewInternalAppSettings(
			core.SetAppCredentials(config.GetString("appid"), config.GetString("appsecret")),           // 必需
			core.SetAppEventKey(config.GetString("verificationtoken"), config.GetString("encryptkey"))) // 非必需，订阅事件、消息卡片时必需

		var confiOptions []core.ConfigOpt
		if config.GetString("ginmode") == "debug" {
			confiOptions = append(confiOptions, core.SetLoggerLevel(core.LoggerLevelDebug))
		}
		app.LarkConf = core.NewConfig(core.DomainFeiShu, appSettings, confiOptions...)
		app.LarkContactService = v3.NewService(app.LarkConf)
		app.DB, err = db.InitDb(config.GetString("db"))
		if err != nil {
			return
		}

		app.AcFilter = util.NewFilterList(config.GetString("accesscontrolpath"))
		err = util.FileWatching(app.AcFilter.GetPath(), func() error {
			return app.AcFilter.Init()
		})
		if err != nil {
			return
		}

		AutoMigrate(app.DB)

		err = app.NotificationRules.LoadFromFile()
		if err != nil {
			return
		}

		err = util.FileWatching(rulePath, func() error {
			return GetApp().NotificationRules.LoadFromFile()
		})
		if err != nil {
			return
		}
		job.Start()

		app.ShutDown = func() {
			log.Println("shutdown function")
			job.Stop()
		}
	})

	return err
}

func GetApp() *App {
	return app
}
