//go:generate ${GOBIN}/mockgen -destination db_mock.go -package=db ${GO_MODULE}/pkg/db Interface,NotificationTransition
package db

import (
	"os"

	"github.com/tidbcloud/jiraport/pkg/config"
	"github.com/tidbcloud/jiraport/pkg/entity"

	"github.com/spf13/viper"
	"gopkg.in/yaml.v2"
	"gorm.io/gorm"
)

type NotificationTransition interface {
	GlobalTransitionWithUpdate(issue *entity.Issue, transEvent config.NotificationTransitionEvent) ([]*entity.NotificationActionExecInfo, error)
	Transition(notificationID uint, transEvent config.NotificationTransitionEvent) (*entity.NotificationActionExecInfo, error)
}

type Interface interface {
	// Issue
	CreateIssue(issue *entity.Issue) error

	// Message
	AddMessage(notificationID uint, msgIndex *entity.MessageIndex) error
	GetMessage(msgIndex *entity.MessageIndex) (*entity.Message, error)

	// Notification
	CreateNotification(policy string, issue *entity.Issue) error
	GetNotification(notificationID uint) (*entity.Notification, error)
	ListNotificationsByIssueKey(issueKey string) ([]entity.Notification, error)

	// NotificationActionExecInfo
	GetNotificationActionExecInfo(actionExecInfoID uint) (*entity.NotificationActionExecInfo, error)
	SetNotificationActionExecInfoFinished(actionExecInfoID uint, status uint) error

	// Assign
	SelectAssigneeFromCandidate(emails []string) (string, error)
}

type Client struct {
	dataDB               *gorm.DB
	notificationPolicies map[string]config.NotificationPolicy
}

func New(dataDB *gorm.DB) (*Client, error) {
	policiesPath := viper.GetString("policy-file")
	notificationPolicies := make(map[string]config.NotificationPolicy)
	policiesStr, err := os.ReadFile(policiesPath)
	if err != nil {
		return nil, err
	}
	err = yaml.Unmarshal(policiesStr, &notificationPolicies)
	if err != nil {
		return nil, err
	}
	err = dataDB.AutoMigrate(&entity.Issue{},
		&entity.Notification{},
		&entity.NotificationActionExecInfo{},
		&entity.Message{},
		&entity.AssignHistory{})
	if err != nil {
		return nil, err
	}
	return &Client{
		dataDB:               dataDB,
		notificationPolicies: notificationPolicies,
	}, nil
}
