package secondaryconfirm

import (
	"github.com/pingcap/errors"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

type DiffParam struct {
	ProjectID        string
	ClusterID        string
	ConfigRevisionID string
}

func (param *DiffParam) Validate() error {
	if len(param.ProjectID) == 0 {
		return errors.New("project_id is empty")
	}
	if len(param.ClusterID) == 0 {
		return errors.New("cluster_id is empty")
	}
	if len(param.ConfigRevisionID) == 0 {
		return errors.New("config_revision_id is empty")
	}
	return nil
}

type ConfigRevisionGetParam struct {
	ProjectID        string `json:"project_id" form:"project_id"`
	ClusterID        string `json:"cluster_id" form:"cluster_id"`
	ConfigRevisionID string `json:"config_revision_id" uri:"config_revision_id" form:"config_revision_id"`
}

func (param *ConfigRevisionGetParam) Validate() error {
	if len(param.ConfigRevisionID) == 0 {
		return errors.New("config_revision_id is empty")
	}
	if len(param.ProjectID) == 0 {
		return errors.New("project_id is empty")
	}
	if len(param.ClusterID) == 0 {
		return errors.New("cluster_id is empty")
	}
	return nil
}

type ConfigRevisionBatchGetParam struct {
	List []ConfigRevisionGetParam `json:"list"`
}

func (param *ConfigRevisionBatchGetParam) Validate() error {
	for _, each := range param.List {
		if err := each.Validate(); err != nil {
			return err
		}
	}

	return nil
}

var emptyConfigPair = ConfigPair{}

type ConfigPair struct {
	CurrentImage string `json:"current_image"`
	NextImage    string `json:"next_image"`
	CurrentToml  string `json:"current_toml"`
	NextToml     string `json:"next_toml"`
}

type VersionPair struct {
	Current string `json:"current"`
	Next    string `json:"next"`
}

type DiffResult struct {
	VersionPair              *VersionPair `json:"version_pair"`
	PDConfigPair             *ConfigPair  `json:"pd_config_pair"`      // always use HotReload, regardless of strategy
	TiProxyConfigPair        *ConfigPair  `json:"tiproxy_config_pair"` // RollingRestart only
	TiDBConfigPair           *ConfigPair  `json:"tidb_config_pair"`    // RollingRestart only
	TiKVConfigPair           *ConfigPair  `json:"tikv_config_pair"`
	TiFlashConfigPair        *ConfigPair  `json:"tiflash_config_pair"`
	TiFlashLearnerConfigPair *ConfigPair  `json:"tiflash_learner_config_pair"`
	BackupPair               *ConfigPair  `json:"backup_config_pair"`    // disposable task, support neither RollingRestart nor HotReload
	RestorePair              *ConfigPair  `json:"restore_config_pair"`   // disposable task, support neither RollingRestart nor HotReload
	LightningPair            *ConfigPair  `json:"lightning_config_pair"` // disposable task, support neither RollingRestart nor HotReload
	TiCDCConfigPair          *ConfigPair  `json:"ticdc_config_pair"`     // RollingRestart only
	SkipApply                bool         `json:"skip_apply"`
	CreationTimestampUnix    int64        `json:"creation_timestamp_unix"`
	CurrConfigRevisionID     string       `json:"curr_config_revision_id"` // is name of ConfigRevision the cluster currently using
}

const (
	ConfigRevisionStatusGenerated = "generated"
	ConfigRevisionStatusOutdated  = "outdated"
	ConfigRevisionStatusApplying  = "applying"
	ConfigRevisionStatusApplied   = "applied"
)

type ConfigRevisionInfo struct {
	ConfigRevisionID string `json:"config_revision_id"`
	Status           string `json:"status" enums:"generated,outdated,applying,applied"`
}

type ApplyParam struct {
	ProjectID            string                       `json:"project_id"`
	ClusterID            string                       `json:"cluster_id"`
	CurrConfigRevisionID string                       `json:"curr_config_revision_id"` // is name of ConfigRevision the cluster currently using
	ConfigRevisionID     string                       `json:"config_revision_id"`
	Strategy             cloudv1.ConfigChangeStrategy `json:"strategy" enums:"RollingRestart,HotReload"`
}

func (param *ApplyParam) Validate() error {
	if len(param.ProjectID) == 0 {
		return errors.New("project_id is empty")
	}
	if len(param.ClusterID) == 0 {
		return errors.New("cluster_id is empty")
	}
	if len(param.ConfigRevisionID) == 0 {
		return errors.New("config_revision_id is empty")
	}
	return nil
}

type ApplyResult struct{}
