package task_manager

import (
	"context"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/errors"
	"go.uber.org/atomic"
	"go.uber.org/fx"

	apierr "github.com/pingcap-inc/clinic/pkg/api/error"
	"github.com/pingcap-inc/clinic/pkg/config"
	"github.com/pingcap-inc/clinic/pkg/task_manager/service"
	_import "github.com/pingcap-inc/clinic/pkg/task_manager/task/import"
)

type APIService struct {
	Params *APIServiceParams
	RG     *gin.RouterGroup
}

type APIServiceParams struct {
	Ctx     context.Context
	Gin     *gin.Engine
	Cfg     *config.Config
	Scanner *_import.ScannerService
}

var initialized atomic.Bool

func NewAPIService(params *APIServiceParams) *APIService {
	svc := &APIService{
		Params: params,
	}

	svc.Params.Gin.Use(gin.Recovery())
	svc.Params.Gin.Use(apierr.ErrorHandlerFn)

	svc.RG = svc.Params.Gin.Group("/task_manager/api/v1")
	return svc
}

func (s *APIService) Start() error {
	if initialized.Swap(true) {
		return errors.New("global api service is already initialized")
	}

	app := fx.New(
		fx.Supply(s.RG, s.Params.Cfg, s.Params.Scanner),
		service.Module,
	)

	if err := app.Start(s.Params.Ctx); err != nil {
		return err
	}

	return nil
}
