// copied from https://github.com/pingcap/tidb-tools/blob/v5.3.0/sync_diff_inspector/config.go
package dm

import (
	"database/sql"

	filter "github.com/pingcap/tidb-tools/pkg/table-filter"
	router "github.com/pingcap/tidb-tools/pkg/table-router"
	"github.com/pingcap/tidb/parser/model"
)

// TableConfig is the config of table.
type TableConfig struct {
	// table's filter to tell us which table should adapt to this config.
	TargetTables []string `toml:"target-tables" json:"target-tables"`
	// Internally used to indicate which specified table in target is using this config.
	Schema string
	Table  string
	// Internally used to distinguish different config.
	ConfigIndex int
	// Internally used to valid config.
	HasMatched bool

	// columns be ignored, will not check this column's data
	IgnoreColumns []string `toml:"ignore-columns"`
	// field should be the primary key, unique key or field with index
	Fields []string `toml:"index-fields"`
	// select range, for example: "age > 10 AND age < 20"
	Range string `toml:"range"`

	TargetTableInfo *model.TableInfo

	// collation config in mysql/tidb
	Collation string `toml:"collation"`

	// specify the chunksize for the table
	ChunkSize int64 `toml:"chunk-size" json:"chunk-size"`
}

// Valid returns true if table's config is valide.
func (t *TableConfig) Valid() bool {
	if len(t.TargetTables) == 0 {
		return false
	}

	return true
}

// DataSource represents the Source Config.
type DataSource struct {
	Host     string `toml:"host" json:"host"`
	Port     int    `toml:"port" json:"port"`
	User     string `toml:"user" json:"user"`
	Password string `toml:"password" json:"password"`
	SqlMode  string `toml:"sql-mode" json:"sql-mode"`
	Snapshot string `toml:"snapshot" json:"snapshot"`

	RouteRules     []string `toml:"route-rules" json:"route-rules"`
	Router         *router.Table
	RouteTargetSet map[string]struct{} `json:"-"`

	Conn *sql.DB
	// SourceType string `toml:"source-type" json:"source-type"`
}

type TaskConfig struct {
	Source       []string `toml:"source-instances" json:"source-instances"`
	Routes       []string `toml:"source-routes" json:"source-routes"`
	Target       string   `toml:"target-instance" json:"target-instance"`
	CheckTables  []string `toml:"target-check-tables" json:"target-check-tables"`
	TableConfigs []string `toml:"target-configs" json:"target-configs"`
	// OutputDir include these
	// 1. checkpoint Dir
	// 2. fix-target-sql Dir
	// 3. summary file
	// 4. sync diff log file
	// 5. fix
	OutputDir string `toml:"output-dir" json:"output-dir"`

	SourceInstances    []*DataSource
	TargetInstance     *DataSource
	TargetTableConfigs []*TableConfig
	TargetCheckTables  filter.Filter

	FixDir        string
	CheckpointDir string
	HashFile      string
}

// Config is the configuration.
type Config struct {
	// log level
	LogLevel string `toml:"-" json:"-"`
	// how many goroutines are created to check data
	CheckThreadCount int `toml:"check-thread-count" json:"check-thread-count"`
	// set true if want to compare rows
	// set false won't compare rows.
	ExportFixSQL bool `toml:"export-fix-sql" json:"export-fix-sql"`
	// only check table struct without table data.
	CheckStructOnly bool `toml:"check-struct-only" json:"check-struct-only"`
	// DMAddr is dm-master's address, the format should like "http://127.0.0.1:8261"
	DMAddr string `toml:"dm-addr" json:"dm-addr"`
	// DMTask string `toml:"dm-task" json:"dm-task"`
	DMTask string `toml:"dm-task" json:"dm-task"`

	DataSources map[string]*DataSource `toml:"data-sources" json:"data-sources"`

	Routes map[string]*router.TableRule `toml:"routes" json:"routes"`

	TableConfigs map[string]*TableConfig `toml:"table-configs" json:"table-configs"`

	Task TaskConfig `toml:"task" json:"task"`
	// config file
	ConfigFile string

	// print version if set true
	PrintVersion bool
}
