package model

import (
	"fmt"

	"github.com/tidbcloud/dataflow-service-e2e/internal/misc"
	"github.com/tidbcloud/dataflow-service-e2e/internal/sample_data"
)

type TiDBServerlessDimensions struct {
	CloudProvider CloudProviderType
	Region        string
	// ServicePlan is empty for legacy callers and therefore preserves the
	// original Starter matching behavior. Essential cases set it explicitly.
	ServicePlan string
}

func NewTiDBServerlessDimensions(m map[string]string) TiDBServerlessDimensions {
	t := TiDBServerlessDimensions{}
	err := misc.MapToStruct(m, &t)
	if err != nil {
		panic(fmt.Sprintf("failed to init TiDBServerlessDimensions, error: %s, map: %v", err.Error(), m))
	}
	return t
}

func (t TiDBServerlessDimensions) Dimensions() map[string]string {
	dimensions := misc.StructToMap(t)
	if t.ServicePlan == "" {
		delete(dimensions, "ServicePlan")
	}
	return dimensions
}

type TiDBServerlessRequirement struct {
	Dedicated bool
	TiDBServerlessDimensions
}

func (t *TiDBServerlessRequirement) Type() string {
	return TiDBServerless
}
func (t *TiDBServerlessRequirement) IsDedicated() bool {
	return t.Dedicated
}

type TiDBServerlessEntity struct {
	TiDBServerlessDimensions

	CreatedByDriver bool

	ClusterID   string
	ProjectID   string
	OrgID       string
	DisplayName string
	// fetch and set by the case driver
	User          string
	Password      string
	Host          string
	Port          string
	PLServiceName string
	PLEndpointID  string
}

func (t *TiDBServerlessEntity) Type() string {
	return TiDBServerless
}
func (t *TiDBServerlessEntity) IsCreatedByDriver() bool {
	return t.CreatedByDriver
}

// MysqlParameter returns the connection descriptor used by SQL fixtures.
// Serverless and Dedicated dependencies deliberately expose the same SQL
// credential shape so validators do not need to manufacture a Dedicated
// entity for an Essential cluster.
func (t *TiDBServerlessEntity) MysqlParameter() *sample_data.MysqlParameter {
	if t == nil {
		return nil
	}
	return &sample_data.MysqlParameter{
		User: t.User, Password: t.Password, Host: t.Host, Port: t.Port,
	}
}

type TiDBServerlessEntities []*TiDBServerlessEntity

func (t TiDBServerlessEntities) ToDependencyEntities() []DependencyEntity {
	var entities []DependencyEntity
	for _, it := range t {
		entities = append(entities, it)
	}
	return entities
}
