package main

import (
	"flag"
	"os"
	"sync"
)

const (
	defaultAddr             = ":8080"
	defaultInternalGRPCAddr = "127.0.0.1:8081"
	defaultLogLevel         = "info"
	defaultProvider         = "kind"
)

var (
	conf     *Config
	confOnce sync.Once
)

type Config struct {
	flagSet *flag.FlagSet

	// LogLevel is the log level.
	LogLevel string `toml:"log-level" json:"log-level"`

	// Addr is the address to listen on.
	Addr string `toml:"addr" json:"addr"`
	// InternalGRPCAddr is the address of internal grpc server.
	InternalGRPCAddr string `toml:"internal-grpc-addr" json:"internal-grpc-addr"`

	// Provider is the cloud provider.
	Provider string `toml:"provider" json:"provider"`

	// DataplaneKubeConfig is the path to the kubeconfig of dataplane k8s. It is usually used
	// for running cluster-agent locally for development
	DataplaneKubeConfig string `toml:"dataplane-kubeconfig" json:"dataplane-kubeconfig"`

	// TiDBOperatorVersion is the version of tidb-operator.
	TiDBOperatorVersion string `toml:"tidb-operator-version" json:"tidb-operator-version"`

	// ClusterNamespace is the namespace where this cluster-agent is deployed.
	ClusterNamespace string `toml:"cluster-namespace" json:"cluster-namespace"`

	// GKEPolicyControl* identifies the only GKE target this cluster-agent may mutate.
	GKEPolicyControlProjectID      string `toml:"gke-policy-control-project-id" json:"gke-policy-control-project-id"`
	GKEPolicyControlLocation       string `toml:"gke-policy-control-location" json:"gke-policy-control-location"`
	GKEPolicyControlClusterName    string `toml:"gke-policy-control-cluster-name" json:"gke-policy-control-cluster-name"`
	GKEPolicyControlFleetProjectID string `toml:"gke-policy-control-fleet-project-id" json:"gke-policy-control-fleet-project-id"`
}

func InitConfig(args []string) error {
	var err error
	confOnce.Do(func() {
		conf = &Config{
			flagSet:          flag.NewFlagSet("http-service", flag.ContinueOnError),
			LogLevel:         defaultLogLevel,
			Addr:             defaultAddr,
			InternalGRPCAddr: defaultInternalGRPCAddr,
			Provider:         defaultProvider,
		}

		conf.flagSet.StringVar(&conf.LogLevel, "L", conf.LogLevel, "log level")
		conf.flagSet.StringVar(&conf.Addr, "addr", conf.Addr, "address to listen on")
		conf.flagSet.StringVar(&conf.InternalGRPCAddr, "internal-grpc-addr", conf.InternalGRPCAddr, "address of internal grpc server")
		conf.flagSet.StringVar(&conf.Provider, "provider", conf.Provider, "cloud provider, e.g. `aws`, `gcp`, `kind`, default is `kind`")
		conf.flagSet.StringVar(&conf.DataplaneKubeConfig, "dataplane-kubeconfig", "", "kubeconfig of dataplane k8s, e.g. `~/.kube/config`")
		conf.flagSet.StringVar(&conf.TiDBOperatorVersion, "tidb-operator-version", "v1", "tidb-operator version")
		conf.flagSet.StringVar(&conf.ClusterNamespace, "cluster-namespace", os.Getenv("POD_NAMESPACE"), "namespace where cluster-agent is deployed")
		conf.flagSet.StringVar(&conf.GKEPolicyControlProjectID, "gke-policy-control-project-id", "", "GKE project id that policy control APIs may operate on")
		conf.flagSet.StringVar(&conf.GKEPolicyControlLocation, "gke-policy-control-location", "", "GKE location that policy control APIs may operate on")
		conf.flagSet.StringVar(&conf.GKEPolicyControlClusterName, "gke-policy-control-cluster-name", "", "GKE cluster name that policy control APIs may operate on")
		conf.flagSet.StringVar(&conf.GKEPolicyControlFleetProjectID, "gke-policy-control-fleet-project-id", "", "GKE fleet project id that policy control APIs may operate on")
		err = conf.flagSet.Parse(args)
	})
	return err
}

func GetConfig() *Config {
	return conf
}
