package proto

import "path"

const RuntimeConfigFileName = "config.json"

// ClusterMetaData only need the version information
type ClusterMetaData struct {
	User    string `yaml:"user"`         // the user to run and manage cluster on remote
	Version string `yaml:"tidb_version"` // the version of TiDB cluster

	Topology *Specification `yaml:"topology"`
}

// Copy from tiup
type PDSpec struct {
	Host                string `yaml:"host"`
	ListenHost          string `yaml:"listen_host,omitempty"`
	AdvertiseClientAddr string `yaml:"advertise_client_addr,omitempty"`
	AdvertisePeerAddr   string `yaml:"advertise_peer_addr,omitempty"`
	SSHPort             int    `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"`
	Imported            bool   `yaml:"imported,omitempty"`
	Patched             bool   `yaml:"patched,omitempty"`
	IgnoreExporter      bool   `yaml:"ignore_exporter,omitempty"`
	// Use Name to get the name with a default value if it's empty.
	Name       string `yaml:"name"`
	ClientPort int    `yaml:"client_port" default:"2379"`
	PeerPort   int    `yaml:"peer_port" default:"2380"`
	DeployDir  string `yaml:"deploy_dir,omitempty"`
	DataDir    string `yaml:"data_dir,omitempty"`
	LogDir     string `yaml:"log_dir,omitempty"`
	NumaNode   string `yaml:"numa_node,omitempty" validate:"numa_node:editable"`
	Arch       string `yaml:"arch,omitempty"`
	OS         string `yaml:"os,omitempty"`
}

func (spec *PDSpec) RealtimeConfigPath(base string) string {
	return path.Join(base, spec.Host, spec.DeployDir, "conf", RuntimeConfigFileName)
}

func (spec *PDSpec) ConfigPath() string {
	return path.Join(spec.Host, spec.DeployDir, "conf", "pd.toml")
}

// Copy from tiup
type TiDBSpec struct {
	Host           string `yaml:"host"`
	ListenHost     string `yaml:"listen_host,omitempty"`
	AdvertiseAddr  string `yaml:"advertise_address,omitempty"`
	SSHPort        int    `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"`
	Imported       bool   `yaml:"imported,omitempty"`
	Patched        bool   `yaml:"patched,omitempty"`
	IgnoreExporter bool   `yaml:"ignore_exporter,omitempty"`
	Port           int    `yaml:"port" default:"4000"`
	StatusPort     int    `yaml:"status_port" default:"10080"`
	DeployDir      string `yaml:"deploy_dir,omitempty"`
	LogDir         string `yaml:"log_dir,omitempty"`
	NumaNode       string `yaml:"numa_node,omitempty" validate:"numa_node:editable"`
	Arch           string `yaml:"arch,omitempty"`
	OS             string `yaml:"os,omitempty"`
}

func (spec *TiDBSpec) RealtimeConfigPath(base string) string {
	return path.Join(base, spec.Host, spec.DeployDir, "conf", RuntimeConfigFileName)
}

func (spec *TiDBSpec) ConfigPath() string {
	return path.Join(spec.Host, spec.DeployDir, "conf", "tidb.toml")
}

// Copy from tiup
type TiKVSpec struct {
	Host                string `yaml:"host"`
	ListenHost          string `yaml:"listen_host,omitempty"`
	AdvertiseAddr       string `yaml:"advertise_addr,omitempty"`
	SSHPort             int    `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"`
	Imported            bool   `yaml:"imported,omitempty"`
	Patched             bool   `yaml:"patched,omitempty"`
	IgnoreExporter      bool   `yaml:"ignore_exporter,omitempty"`
	Port                int    `yaml:"port" default:"20160"`
	StatusPort          int    `yaml:"status_port" default:"20180"`
	AdvertiseStatusAddr string `yaml:"advertise_status_addr,omitempty"`
	DeployDir           string `yaml:"deploy_dir,omitempty"`
	DataDir             string `yaml:"data_dir,omitempty"`
	LogDir              string `yaml:"log_dir,omitempty"`
	Offline             bool   `yaml:"offline,omitempty"`
	NumaNode            string `yaml:"numa_node,omitempty" validate:"numa_node:editable"`
	Arch                string `yaml:"arch,omitempty"`
	OS                  string `yaml:"os,omitempty"`
}

func (spec *TiKVSpec) RealtimeConfigPath(base string) string {
	return path.Join(base, spec.Host, spec.DeployDir, "conf", RuntimeConfigFileName)
}

func (spec *TiKVSpec) ConfigPath() string {
	return path.Join(spec.Host, spec.DeployDir, "conf", "tikv.toml")
}

// TiFlashSpec represents the TiFlash topology specification in topology.yaml
type TiFlashSpec struct {
	Host                 string                 `yaml:"host"`
	SSHPort              int                    `yaml:"ssh_port,omitempty" validate:"ssh_port:editable"`
	Imported             bool                   `yaml:"imported,omitempty"`
	Patched              bool                   `yaml:"patched,omitempty"`
	IgnoreExporter       bool                   `yaml:"ignore_exporter,omitempty"`
	TCPPort              int                    `yaml:"tcp_port" default:"9000"`
	HTTPPort             int                    `yaml:"http_port" default:"8123"`
	FlashServicePort     int                    `yaml:"flash_service_port" default:"3930"`
	FlashProxyPort       int                    `yaml:"flash_proxy_port" default:"20170"`
	FlashProxyStatusPort int                    `yaml:"flash_proxy_status_port" default:"20292"`
	StatusPort           int                    `yaml:"metrics_port" default:"8234"`
	DeployDir            string                 `yaml:"deploy_dir,omitempty"`
	DataDir              string                 `yaml:"data_dir,omitempty" validate:"data_dir:expandable"`
	LogDir               string                 `yaml:"log_dir,omitempty"`
	TmpDir               string                 `yaml:"tmp_path,omitempty"`
	Offline              bool                   `yaml:"offline,omitempty"`
	NumaNode             string                 `yaml:"numa_node,omitempty" validate:"numa_node:editable"`
	Config               map[string]interface{} `yaml:"config,omitempty" validate:"config:ignore"`
	LearnerConfig        map[string]interface{} `yaml:"learner_config,omitempty" validate:"learner_config:ignore"`
	Arch                 string                 `yaml:"arch,omitempty"`
	OS                   string                 `yaml:"os,omitempty"`
}

// Specification represents the specification of topology.yaml
type Specification struct {
	TiDBServers    []*TiDBSpec    `yaml:"tidb_servers"`
	TiKVServers    []*TiKVSpec    `yaml:"tikv_servers"`
	PDServers      []*PDSpec      `yaml:"pd_servers"`
	TiFlashServers []*TiFlashSpec `yaml:"tiflash_servers"`
}
