package shared

import "time"

// EnvBinding represents a direct binding from an env variable to a go kind. Along with gookit/config, its primal goal
// is to unpack environment variables into a Go value. We do so with reflection, and this data structure is just a step
// in between.
type EnvBinding struct {
	EnvVars     []string // name of the environment var.
	Destination any      // pointer to the original config value to modify.
}

// Log defines the available logging configuration.
type Log struct {
	Level  string `yaml:"level" env:"OC_LOG_LEVEL" desc:"The log level. Valid values are: 'panic', 'fatal', 'error', 'warn', 'info', 'debug', 'trace'." introductionVersion:"1.0.0"`
	Pretty bool   `yaml:"pretty" env:"OC_LOG_PRETTY" desc:"Activates pretty log output." introductionVersion:"1.0.0"`
	Color  bool   `yaml:"color" env:"OC_LOG_COLOR" desc:"Activates colorized log output." introductionVersion:"1.0.0"`
	File   string `yaml:"file" env:"OC_LOG_FILE" desc:"The path to the log file. Activates logging to this file if set." introductionVersion:"1.0.0"`
}

// TokenManager is the config for using the reva token manager
type TokenManager struct {
	JWTSecret string `mask:"password" yaml:"jwt_secret" env:"OC_JWT_SECRET" desc:"The secret to mint and validate jwt tokens." introductionVersion:"1.0.0"`
}

// Reva defines all available REVA client configuration.
type Reva struct {
	Address string        `yaml:"address" env:"OC_REVA_GATEWAY" desc:"The CS3 gateway endpoint." introductionVersion:"1.0.0"`
	TLS     GRPCClientTLS `yaml:"tls"`
}

type GRPCClientTLS struct {
	Mode   string `yaml:"mode" env:"OC_GRPC_CLIENT_TLS_MODE" desc:"TLS mode for grpc connection to the go-micro based grpc services. Possible values are 'off', 'insecure' and 'on'. 'off': disables transport security for the clients. 'insecure' allows using transport security, but disables certificate verification (to be used with the autogenerated self-signed certificates). 'on' enables transport security, including server certificate verification." introductionVersion:"1.0.0"`
	CACert string `yaml:"cacert" env:"OC_GRPC_CLIENT_TLS_CACERT" desc:"Path/File name for the root CA certificate (in PEM format) used to validate TLS server certificates of the go-micro based grpc services." introductionVersion:"1.0.0"`
}

type GRPCServiceTLS struct {
	Enabled bool   `yaml:"enabled" env:"OC_GRPC_TLS_ENABLED" desc:"Activates TLS for the grpc based services using the server certifcate and key configured via OC_GRPC_TLS_CERTIFICATE and OC_GRPC_TLS_KEY. If OC_GRPC_TLS_CERTIFICATE is not set a temporary server certificate is generated - to be used with OC_GRPC_CLIENT_TLS_MODE=insecure." introductionVersion:"1.0.0"`
	Cert    string `yaml:"cert" env:"OC_GRPC_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the grpc services." introductionVersion:"1.0.0"`
	Key     string `yaml:"key" env:"OC_GRPC_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate to use for the grpc services." introductionVersion:"1.0.0"`
}

type HTTPServiceTLS struct {
	Enabled bool `yaml:"enabled" env:"OC_HTTP_TLS_ENABLED" desc:"Activates TLS for the http based services using the server certifcate and key configured via OC_HTTP_TLS_CERTIFICATE and OC_HTTP_TLS_KEY. If OC_HTTP_TLS_CERTIFICATE is not set a temporary server certificate is generated - to be used with PROXY_INSECURE_BACKEND=true." introductionVersion:"1.0.0"`

	Cert string `yaml:"cert" env:"OC_HTTP_TLS_CERTIFICATE" desc:"Path/File name of the TLS server certificate (in PEM format) for the http services." introductionVersion:"1.0.0"`
	Key  string `yaml:"key" env:"OC_HTTP_TLS_KEY" desc:"Path/File name for the TLS certificate key (in PEM format) for the server certificate to use for the http services." introductionVersion:"1.0.0"`
}

type Cache struct {
	Store              string        `yaml:"store" env:"OC_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"1.0.0"`
	Nodes              []string      `yaml:"nodes" env:"OC_CACHE_STORE_NODES" desc:"A comma separated list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store." introductionVersion:"1.0.0"`
	Database           string        `yaml:"database" env:"OC_CACHE_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"1.0.0"`
	Table              string        `yaml:"table" env:"OC_CACHE_STORE_TABLE" desc:"The database table the store should use." introductionVersion:"1.0.0"`
	TTL                time.Duration `yaml:"ttl" env:"OC_CACHE_TTL" desc:"Time to live for events in the store. The duration can be set as number followed by a unit identifier like s, m or h." introductionVersion:"1.0.0"`
	DisablePersistence bool          `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
	AuthUsername       string        `yaml:"auth_username" env:"OC_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
	AuthPassword       string        `yaml:"auth_password" env:"OC_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
}

// Commons holds configuration that are common to all extensions. Each extension can then decide whether
// to overwrite its values.
type Commons struct {
	TracesExporter     string          `yaml:"traces_exporter" env:"OTEL_TRACES_EXPORTER" desc:"The exporter used for traces. Supports 'otlp', 'console' and 'none' (default)." introductionVersion:"6.0.0"`
	Log                *Log            `yaml:"log"`
	Cache              *Cache          `yaml:"cache"`
	GRPCClientTLS      *GRPCClientTLS  `yaml:"grpc_client_tls"`
	GRPCServiceTLS     *GRPCServiceTLS `yaml:"grpc_service_tls"`
	HTTPServiceTLS     HTTPServiceTLS  `yaml:"http_service_tls"`
	OpenCloudURL       string          `yaml:"opencloud_url" env:"OC_URL" desc:"URL, where OpenCloud is reachable for users." introductionVersion:"1.0.0"`
	TokenManager       *TokenManager   `mask:"struct" yaml:"token_manager"`
	Reva               *Reva           `yaml:"reva"`
	MachineAuthAPIKey  string          `mask:"password" yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY" desc:"Machine auth API key used to validate internal requests necessary for the access to resources from other services." introductionVersion:"1.0.0"`
	TransferSecret     string          `mask:"password" yaml:"transfer_secret,omitempty" env:"REVA_TRANSFER_SECRET" desc:"The secret used for signing the requests towards the data gateway for up- and downloads." introductionVersion:"1.0.0"`
	URLSigningSecret   string          `yaml:"url_signing_secret" env:"OC_URL_SIGNING_SECRET" desc:"The shared secret used to sign URLs e.g. for image downloads by the web office suite." introductionVersion:"4.0.0"`
	SystemUserID       string          `yaml:"system_user_id" env:"OC_SYSTEM_USER_ID" desc:"ID of the OpenCloud storage-system system user. Admins need to set the ID for the storage-system system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format." introductionVersion:"1.0.0"`
	SystemUserAPIKey   string          `mask:"password" yaml:"system_user_api_key" env:"SYSTEM_USER_API_KEY" desc:"API key for all system users." introductionVersion:"1.0.0"`
	AdminUserID        string          `yaml:"admin_user_id" env:"OC_ADMIN_USER_ID" desc:"ID of a user, that should receive admin privileges. Consider that the UUID can be encoded in some LDAP deployment configurations like in .ldif files. These need to be decoded beforehand." introductionVersion:"1.0.0"`
	MultiTenantEnabled bool            `yaml:"multi_tenant_enabled" env:"OC_MULTI_TENANT_ENABLED" desc:"Set this to true to enable multi-tenant support." introductionVersion:"4.0.0"`

	// NOTE: you will not fing GRPCMaxReceivedMessageSize size being used in the code. The envvar is actually extracted in revas `pool` package: https://github.com/cs3org/reva/blob/edge/pkg/rgrpc/todo/pool/connection.go
	// It is mentioned here again so it is documented
	GRPCMaxReceivedMessageSize int `env:"OC_GRPC_MAX_RECEIVED_MESSAGE_SIZE" desc:"The maximum body size for grpc requests. Defaults to '10240000' bytes (10MB). Note that large values can potentially hide errors but may lead to network timeouts. Should only be changed temporarily to regain access for large folders with 25.000+ files to copy out data." introductionVersion:"1.0.0"`
}
