package config

import (
	"github.com/tidbcloud/core-portal/internal/central/pkg/ratecontroller/types"
)

var globalConf *CentralConfig = &CentralConfig{}

type CentralConfig struct {
	ServerConfig      ServerConfig      `mapstructure:"server"`
	SessionConfig     SessionConfig     `mapstructure:"session"`
	GrpcConfig        GrpcConfig        `mapstructure:"grpc"`
	MysqlConfig       MysqlConfig       `mapstructure:"mysql"`
	GardenerConfig    GardenerConfig    `mapstructure:"gardener"`
	InfraAPIConfig    InfraAPIConfig    `mapstructure:"infraAPI"`
	AwsConfig         AwsConfig         `mapstructure:"aws"`
	ProxyConfig       ProxyConfig       `mapstructure:"proxy"`
	InfraConfig       InfraConfig       `mapstructure:"infra"`
	Auth0Config       Auth0Config       `mapstructure:"auth0"`
	GrafanaConfig     GrafanaConfig     `mapstructure:"grafana"`
	RateControlConfig RateControlConfig `mapstructure:"rateControl"`
	ClusterConfig     ClusterConfig     `mapstructure:"cluster"`
}

type ClusterConfig struct {
	DevTierNodeSize       string `mapstructure:"devTierNodeSize" default:"Shared0"`
	DevTierStorageSizeGib int64  `mapstructure:"devTierStorageSizeGib" default:"1"`
}

type GrpcConfig struct {
	CoreSvcAddr       string `mapstructure:"coreSvcAddr" default:"dbaas-core-svc-server-grpc:8888"`
	DataflowSvcAddr   string `mapstructure:"dataflowSvcAddr" default:"dataflow-grpc:10000"`
	AccountAclSvcAddr string `mapstructure:"accountAclSvcAddr" default:"account-acl-grpc:10000"`
}

type RateControlConfigItem struct {
	Scene *types.Scene  `mapstructure:"scene"`
	Rates []*types.Rate `mapstructure:"rates"`
}

type RateControlConfig struct {
	InviteUser               RateControlConfigItem `mapstructure:"inviteUser"`
	RegistrationVerification RateControlConfigItem `mapstructure:"registrationVerification"`
	SendPasswordVerifyCode   RateControlConfigItem `mapstructure:"sendPasswordVerifyCode"`
}

type ServerConfig struct {
	// Log level: debug, info, warn, error, fatal
	LogLevel         string `mapstructure:"logLevel" default:"info" validate:"oneof=debug info warn error fatal"`
	EnableDBQueryLog bool   `mapstructure:"enableDBQueryLog" default:"false"`

	Stage    string `mapstructure:"stage" validate:"required"`
	GrpcPort int    `mapstructure:"grpcPort" default:"10000"`
	//the central metrics port
	MetricsPort uint16 `mapstructure:"metricsPort" default:"9090"`
	// session secret salt conf
	SaltSecret string `mapstructure:"saltSecret" required:"true"`
	// mailgun conf
	MailGunApiKey string `mapstructure:"mailGunApiKey" required:"true"`
	// sendgrid conf
	SendgridApiKey string `mapstructure:"sendgridApiKey" required:"true"`

	SentryConf SentryConfig `mapstructure:"sentry"`

	SecretStore *SecretConfig `mapstructure:"secret"`

	ManagementPortalInitUserEmail *string `mapstructure:"managementPortalInitUserEmail" default:"cloud@pingcap.com"`

	// BizOpsTeamEmail is the email of business ops team
	BizOpsTeamEmail string `mapstructure:"bizOpsTeamEmail"`

	// limited project cidr
	LimitedProjectCIDR []string `mapstructure:"limitedProjectCIDR"`

	UsePrivilegedTiDB bool `mapstructure:"usePrivilegedTiDB" default:"false"`

	// check if loaded remote config
	RemoteConfigEnabled bool `mapstructure:"remoteConfigEnabled"`
}

type SentryConfig struct {
	DSN         string `mapstructure:"dsn"`
	Environment string `mapstructure:"env"`
	LogLevel    string `mapstructure:"logLevel" default:"warn"`
}

type SessionConfig struct {
	// A secret to encrypt or derive sessions.
	// Currently only Debug Portal implements session.
	Secret string `mapstructure:"secret" validate:"required"`
}

type SecretConfig struct {
	SecretKey string `mapstructure:"secretKey"`
	Region    string `mapstructure:"region"`
}

type GrafanaConfig struct {
	Server           string `mapstructure:"server"  default:"https://grafana.oauth.dev.shared.aws.tidbcloud.com/"`
	APIKey           string `mapstructure:"apiKey"`
	TidbDashboardTag string `mapstructure:"tidbDashboardTag" default:"tidb-mixin"`
}

// infra configurations
type InfraConfig struct {
	// dbaas central service region
	Region     string `mapstructure:"region" required:"true" default:"us-west-2"`
	CMKArn     string `mapstructure:"cmkArn" required:"true"`
	GcpProject string `mapstructure:"gcpProject" required:"true"`

	ConfigServiceURL string `mapstructure:"configServiceURL" required:"true" default:"http://config-service.gitops:8090"`

	EnableTopSQL bool `mapstructure:"enableTopSQL" required:"false" default:"true"`
}

type Auth0Config struct {
	Auth0ManagementClientID     string `mapstructure:"auth0ManagementClientID" required:"true"`
	Auth0ManagementClientSecret string `mapstructure:"auth0ManagementClientSecret" required:"true"`
	Auth0DatabaseConnectionName string `mapstructure:"auth0DatabaseConnectionName" required:"true" default:"custom-email"`

	Auth0Domain   string `mapstructure:"auth0Domain" required:"true"`
	Auth0Audience string `mapstructure:"auth0Audience" required:"true"`
	Auth0Secret   string `mapstructure:"auth0Secret" required:"true"`

	ManagementPortalAuth0Domain         string `mapstructure:"managementPortalAuth0Domain" required:"true"`
	ManagementPortalAuth0Audience       string `mapstructure:"managementPortalAuth0Audience" required:"true"`
	ManagementPortalAuth0Secret         string `mapstructure:"managementPortalAuth0Secret" required:"true"`
	ManagementPortalAuth0ClientAudience string `mapstructure:"managementPortalAuth0ClientAudience" required:"true"`
}

type ProxyConfig struct {
	Auth0Domain       string `mapstructure:"auth0Domain" required:"true"`
	Auth0ClientID     string `mapstructure:"auth0ClientID" required:"true"`
	Auth0ClientSecret string `mapstructure:"auth0ClientSecret" required:"true"`
	Auth0Audience     string `mapstructure:"auth0Audience" required:"true"`
}

type AwsConfig struct {
	PCAArn    string `mapstructure:"pcaArn" required:"true"`
	Region    string `mapstructure:"region" required:"true"`
	AccountID string `mapstructure:"accountID" required:"true"`
}

type GardenerConfig struct {
	GardenerProjectName string `mapstructure:"gardenerProjectName" default:"core" required:"true"`
	// kubeconfig file for base cluster, ignore if in cluster
	KubeConfigPath string `mapstructure:"kubeConfigPath"`
}

// InfraAPIConfig is the configration items for infra API operations.
type InfraAPIConfig struct {
	// kubeconfig file for the infra API server, ignore this to use the default secret
	KubeConfigPath string `mapstructure:"kubeConfigPath"`

	// ref https://github.com/tidbcloud/infra-api/pull/79
	// Enable this too keep the 'key' of resources do not change in infra-api.
	// will use projectID@dbaas as projectID@infra-api
	ProjectIDAsInfraProjectID bool `mapstructure:"projectIDAsInfraProjectID"`
}

// NeedInit returns true if we need to initialize the infra API.
func (ic *InfraAPIConfig) NeedInit() bool {
	return true
}

type MysqlConfig struct {
	Host     string `mapstructure:"host" default:"host"`
	User     string `mapstructure:"user" default:"root"`
	Port     uint16 `mapstructure:"port" default:"4000"`
	Password string `mapstructure:"password" required:"true"`
	Database string `mapstructure:"database" default:"dbaas"`
}
