package main

import (
	"context"
	"flag"
	"time"

	"github.com/gin-contrib/cors"
	"github.com/tidbcloud/auditlog/internal/auth"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"github.com/tidbcloud/tiinf/sdk/auditlog"
	"github.com/tidbcloud/tiinf/tiinf"
	"github.com/tidbcloud/tiinf/transport/http/tigin"
	"go.uber.org/zap"

	"github.com/tidbcloud/auditlog/configs"
	"github.com/tidbcloud/auditlog/internal/controller"
	"github.com/tidbcloud/auditlog/internal/dao"
	"github.com/tidbcloud/auditlog/internal/entity"
	"github.com/tidbcloud/auditlog/third_party/account"
)

var (
	configPath = flag.String("config", "/etc/dbaas/config.yaml", "DBaaS configuration file path")
)

// @BasePath /api/v1/audit
func main() {
	flag.Parse()
	configs.SetConfigPath(*configPath)

	ctx := context.TODO()
	tilog.Info(ctx, "auditservice-subscriber start")

	if err := configs.LoadRemoteConfig(ctx); err != nil {
		tilog.Panic(ctx, "viper load remote config error", zap.Error(err))
		return
	}

	// Init db
	cfg := configs.GetConfig()
	if err := entity.InitDB(cfg, false); err != nil {
		tilog.Panic(ctx, "failed to init db", zap.Error(err))
		return
	}

	// Init Eventbus
	err := auditlog.InitAuditLogSDK(ctx, time.Second*time.Duration(10))
	if err != nil {
		tilog.Panic(ctx, "failed to init auditlog", zap.Error(err))
		return
	}

	// init service
	db := entity.GetDB()
	controller.InitAuditService(ctx, cfg, db, dao.NewAuditDao())

	accountSvc := account.NewAccountSvc(ctx, cfg)

	inf := tiinf.NewInf()
	err = inf.Init(tiinf.WithConfigFile(*configPath))
	if err != nil {
		tilog.Panic(ctx, "failed to init tiinf", zap.Error(err))
		return
	}

	engine := inf.GinEngine()
	corsConfig := cors.DefaultConfig()
	corsConfig.AllowAllOrigins = true
	corsConfig.AddAllowHeaders("Authorization")
	engine.Use(cors.New(corsConfig))

	engine.GET("/healthz", tigin.Ping)
	engine.GET("/ping", tigin.Ping)

	apiGroup := engine.Group("/api/v1/audit")
	apiGroup.Use(tigin.CheckUserAndPermission(accountSvc.GetAccountServiceClient()))
	{
		apiGroup.GET("/:org_id/settings", controller.HandleQuerySettings)
		apiGroup.PUT("/:org_id/settings", controller.HandleUpdateSettings)
		apiGroup.GET("/event_types", controller.HandleQueryEventTypes)
		apiGroup.GET("/:org_id/audit_logs", controller.HandleQueryAuditLog)
		apiGroup.GET("/:org_id/audit_logs/export", controller.HandleExportAuditLog)
	}

	opsGroup := engine.Group("/api/v1/ops-audit")
	opsGroup.Use(auth.AuthnOpsAK())
	{
		opsGroup.GET("/:org_id/settings", controller.HandleOpsQuerySettings)
		opsGroup.GET("/event_types", controller.HandleQueryEventTypes)
		opsGroup.GET("/:org_id/audit_logs", controller.HandleOpsQueryAuditLog)
		opsGroup.GET("/:org_id/audit_logs/export", controller.HandleOpsExportAuditLog)
	}

	controller.RegisterOpenApiRouter(engine)

	inf.Run() //nolint:errcheck
}
