package config

import "github.com/tidbcloud/core-svc/knife"

var globalConf = &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"`
	RBACConfig     RBACConfig                      `mapstructure:"rbacConfig"`
	Auth0Config    Auth0Config                     `mapstructure:"auth0"`
	GrafanaConfig  GrafanaConfig                   `mapstructure:"grafana"`
	ClusterConfig  ClusterConfig                   `mapstructure:"cluster"`
	FeatureGates   map[FeatureGateName]FeatureGate `mapstructure:"featureGates"`
	Degradation    knife.DegradationConfig         `mapstructure:"degradation"`
}

type FeatureGateName string

var (
	// FeatureGateNameNewRBAC determines whether org_audit_admin can access database audit log
	FeatureGateNameNewRBAC FeatureGateName = "new_rbac"

	// whether to enable dedicated tidb management service
	DedicatedTiDBMgmt FeatureGateName = "dedicated_tidb_mgmt"

	EnableTempoProxy FeatureGateName = "enable_tempo_proxy"

	DisableCleanResource FeatureGateName = "disable_clean_resource"
)

// FeatureGate ... https://pingcap.feishu.cn/docx/Nj1gdJxBnoWiO2xIHCdcWN7unqf
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"`
	EnabledRegions  []string `mapstructure:"enabledRegions"`

	// Disable the feature for the specified tenants.
	DisabledTenants []uint64 `mapstructure:"disabledTenants"`
	// Disable the feature for the specified projects.
	DisabledProjects []uint64 `mapstructure:"disabledProjects"`
	DisabledRegions  []string `mapstructure:"disabledRegions"`

	// Required the feature in these regions
	RequiredRegions []string `mapstructure:"requiredRegions"`

	// Required if the organization is created after the specified time.
	AffectOrgCreatedAfter string `mapstructure:"affectOrgCreatedAfter" default:"2099-01-01T00:00:00Z"`
}

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"`
	DedicatedGlobalAddr    string `mapstructure:"dedicatedGlobalAddr" default:"dedicated-global-service.tidb-management-service:10000"`
	CoreProxyAddr          string `mapstructure:"coreProxyAddr" default:"tempo-proxy.tidb-management-service:10102"`
	MgmtServiceAddr        string `mapstructure:"mgmtServiceAddr" default:"tidb-mgmt-service.tidb-management-service:10001"`
	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"`
	RBACServerAddr         string `mapstructure:"rbacServerAddr"`
	DevopsSvcAddr          string `mapstructure:"devopsSvcAddr" default:"devops-server-grpc.devops:8089"`
	WaitTimeoutSec         int64  `mapstructure:"waitTimeoutSec" default:"15"`
}

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"`
	EnableMySQLTLS   bool `mapstructure:"enableMySQLTLS" 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" validate:"required"`

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

	ForbidM2mRequest bool `mapstructure:"forbidM2mRequest" default:"false"`

	MockAuditLogSDK bool `mapstructure:"mockAuditLogSDK"`
}

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"`
	// IP Allow list
	IPAllowList []string `mapstructure:"ipAllowList"`
}

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

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

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

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

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

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

type RBACConfig struct {
	Enable                           bool              `mapstructure:"enable" default:"false"`
	Dryrun                           bool              `mapstructure:"dryrun" default:"false"`
	MergeRBACPathPattern2ResourceMap map[string]string `mapstructure:"mergeRBACPathPattern2ResourceMap"`
}

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

type AwsConfig struct {
	PCAArn    string `mapstructure:"pcaArn" validate:"required"`
	AccountID string `mapstructure:"accountID" validate:"required"`
}

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

// InfraAPIConfig is the configuration items for infra API operations.
type InfraAPIConfig struct {
	// kubeconfig file for the infra API server
	KubeConfigPath string `mapstructure:"kubeConfigPath" validate:"required"`

	// ref https://github.com/tidbcloud/infra-api/pull/79
	// Enable this to 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" validate:"required"`
	Database string `mapstructure:"database" default:"dbaas"`
	LogLevel string `mapstructure:"logLevel" default:"info"`
}

const (
	// CoreSvcAPIKey is the api key of core service API key in env.
	CoreSvcAPIKey = "core_svc_api_key"
)
