package config

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"`
	ClusterConfig  ClusterConfig                   `mapstructure:"cluster"`
	FeatureGates   map[FeatureGateName]FeatureGate `mapstructure:"featureGates"`
}

type FeatureGateName string

const (
	EKSFullManager FeatureGateName = "eksfull"
	ARMOnly        FeatureGateName = "arm_only"
)

// https://pingcap.feishu.cn/wiki/wikcnntXnzVrkN5JfTC4hJwtXWe
type FeatureGate struct {
	// If `All` is true, this feature gate will be enabled for all except DisabledTenants and DisabledProjects.
	// If `All` is false, this feature gate will be disabled for all except EnabledTenants and EnabledProjects.
	All bool `mapstructure:"all" default:"false"`
	// Enable the feature for the specified tenants.
	EnabledTenants []uint64 `mapstructure:"enabledTenants"`
	// Enable the feature for the specified projects.
	EnabledProjects []uint64 `mapstructure:"enabledProjects"`
	// Disable the feature for the specified tenants.
	DisabledTenants []uint64 `mapstructure:"disabledTenants"`
	// Disable the feature for the specified projects.
	DisabledProjects []uint64 `mapstructure:"disabledProjects"`
}

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"`
	AccountProviderSvcAddr string `mapstructure:"accountProviderSvcAddr" default:"account-provider-grpc:10000"`
}

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"`
	InternalPortalListenAddr string `mapstructure:"internalPortalListenAddr" default:"0.0.0.0:8081"`
	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"`

	// 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"`
}

type Auth0Config struct {
	Auth0ManagementClientID     string `mapstructure:"auth0ManagementClientID" required:"true"`
	Auth0ManagementClientSecret string `mapstructure:"auth0ManagementClientSecret" required:"true"`

	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"`
}

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"`
}
