package config

import (
	"time"
)

type RootConfig struct {
	SecretSource SecretSource `yaml:"secret_source"`

	Log LogConfig `yaml:"log"`

	Asset AssetConfig `yaml:"asset"`

	MySQL DatabaseConfig `yaml:"mysql"`

	EventBus EventBusConfig `yaml:"eventbus"`

	APIServer APIServerConfig `yaml:"apiServer"`

	GrpcServer GrpcServerConfig `yaml:"grpcServer"`

	Services Services `yaml:"services"`

	Controllers Controllers `yaml:"controllers"`

	Clients Clients `yaml:"clients"`

	DbaasAddr DbaasAddrConfig `yaml:"dbaasAddr"`
}

type SecretSource struct {
	RootConfigSecretName string `yaml:"rootConfigSecretName"`

	AWSASM    *SecretSourceAWSASM    `yaml:"awsASM"`
	AliyunKMS *SecretSourceAliyunKMS `yaml:"aliyunKMS"`
	AliyunOSS *SecretSourceAliyunOSS `yaml:"aliyunOSS"`
}

type LogConfig struct {
	Level int16 `yaml:"level" default:"0"`

	AccessLogPath       string `yaml:"accessLogPath" default:"/var/log/devops-server/access.log"`
	AccessLogMaxSize    int    `yaml:"accessLogMaxSize" default:"500"` // megabytes
	AccessLogMaxBackups int    `yaml:"accessLogMaxBackups" default:"3"`
	AccessLogMaxAge     int    `yaml:"accessLogMaxAge" default:"7"` // days
}

type AssetConfig struct {
	BucketName string `yaml:"bucketName" validate:"required"` // S3 bucket name
}

type DatabaseConfig struct {
	Host     string            `yaml:"host" validate:"required"`
	Port     uint16            `yaml:"port" validate:"required"`
	User     string            `yaml:"user" validate:"required"`
	Password string            `yaml:"password" validate:"required"` // Password may be set directly or resolved via RootConfig.SecretSource
	Database string            `yaml:"database" validate:"required"`
	Params   map[string]string `yaml:"params"`

	TLSConfigKey    string        `yaml:"tlsConfigKey"`
	DailTimeout     time.Duration `yaml:"dailTimeout" default:"60s"`
	ReadTimeout     time.Duration `yaml:"readTimeout" default:"30s"`
	WriteTimeout    time.Duration `yaml:"writeTimeout" default:"30s"`
	ConnMaxLifetime time.Duration `yaml:"connMaxLifetime" default:"3m"`
	MaxIdleConns    int           `yaml:"maxIdleConns" default:"100"`
	MaxOpenConns    int           `yaml:"maxOpenConns" default:"100"`

	LogLevel         int           `yaml:"logLevel" default:"4"` // 1: silent, 2: error, 3: warn, 4: info
	LogSlowThreshold time.Duration `yaml:"logSlowThreshold" default:"200ms"`
	TraceQuerySQL    bool          `yaml:"traceQuerySQL" default:"false"`
}

type EventBusAuthSASLConfig struct {
	Username string `yaml:"username" validate:"required"`
	Password string `yaml:"password" validate:"required"`
}

type EventBusConfig struct {
	Disable  bool                    `yaml:"disable" default:"false"`
	AppName  string                  `yaml:"appName" default:"devops"`
	AuthSASL *EventBusAuthSASLConfig `yaml:"authSASL"`
}

type SecretSourceAWSASM struct {
	// Region is the default region.
	Region string `yaml:"region" default:"us-west-2"`
}

type SecretSourceAliyunKMS struct {
	// Region is the default region.
	Region string `yaml:"region" default:"us-west-2"`
	// AssumeRoleARN is the role ARN to assume when accessing the secret. If not set, the default credential will be used.
	AssumeRoleARN string `yaml:"assumeRoleARN"`
}

type SecretSourceAliyunOSS struct {
	// Bucket is the name of OSS bucket.
	Bucket string `yaml:"bucket" validate:"required"`
	// Region is the OSS bucket region.
	Region string `yaml:"region" validate:"required"`
}

type LarkCertConfig struct {
	LarkBaseURL       string `yaml:"larkBaseURL" default:"pingcap.feishu.cn"`
	AppCode           string `yaml:"appCode" validate:"required"`
	AppSecret         string `yaml:"appSecret" validate:"required"`         // READ FROM ASM
	EncryptKey        string `yaml:"encryptKey" validate:"required"`        // READ FROM ASM
	VerificationToken string `yaml:"verificationToken" validate:"required"` // READ FROM ASM
}

type APIServerConfig struct {
	ListenAddr        string        `yaml:"listenAddr" default:":8080"`
	ReadHeaderTimeout time.Duration `yaml:"readHeaderTimeout" default:"10s"`
	TrustedProxies    []string      `yaml:"trustedProxies"`

	Auth AuthConfig `yaml:"auth"`
}

type GrpcServerConfig struct {
	ListenAddr string `yaml:"listenAddr" default:":8081"`
}

type AuthConfig struct {
	AuthDomain     string `yaml:"authDomain" validate:"required"`
	AuthAudience   string `yaml:"authAudience" validate:"required"` // READ FROM ASM
	UserEmailClaim string `yaml:"userEmailClaim" default:"email"`   // The claim is injected in Auth0's Actions.
}

type MgmtServiceConfig struct {
	HTTPAddr  string `yaml:"httpAddr" validate:"required"`  // The address of the management HTTP
	HTTPToken string `yaml:"httpToken" validate:"required"` // READ FROM ASM
}
