package flow

import (
	"flag"
	"validate/dbctrl"
)

func MakeupDownstreamCommand() *MakeupDownstreamCommandCtx {
	ca := &MakeupDownstreamCommandCtx{
		ClusterMigrationSubCommandCtx{
			fs: flag.NewFlagSet(MakeupDownstreamClusterCommand, flag.ContinueOnError),
		},
	}
	ca.fs.StringVar(&ca.CommandTarget, "target", "all", "Sub-actions of the command.")

	ca.fs.StringVar(&ca.PrimaryAddress.Host, PrefixPrimaryClusterAddr+"host", "127.0.0.1", "Host address of the primary TiDB Cluster, 'localhost' as default.")
	ca.fs.IntVar(&ca.PrimaryAddress.Port, PrefixPrimaryClusterAddr+"port", 4000, "Port of the primary TiDB Cluster, 4000 as default.")
	ca.fs.StringVar(&ca.PrimaryAddress.Database, PrefixPrimaryClusterAddr+"dbname", "mysql", "Database name of the primary TiDB Cluster, 'mysql' as default.")
	ca.fs.StringVar(&ca.PrimaryAddress.Account, PrefixPrimaryClusterAddr+"account", "root", "Database account of the primary TiDB Cluster, 'root' as default.")
	ca.fs.StringVar(&ca.PrimaryAddress.Password, PrefixPrimaryClusterAddr+"password", "", "Host address of the primary TiDB Cluster, '' as default.")

	ca.fs.StringVar(&ca.DownstreamAddress.Host, PrefixDownstreamClusterAddr+"host", "127.0.0.1", "Host address of the primary TiDB Cluster, 'localhost' as default.")
	ca.fs.IntVar(&ca.DownstreamAddress.Port, PrefixDownstreamClusterAddr+"port", 4000, "Port of the primary TiDB Cluster, 4000 as default.")
	ca.fs.StringVar(&ca.DownstreamAddress.Database, PrefixDownstreamClusterAddr+"dbname", "mysql", "Database name of the primary TiDB Cluster, 'mysql' as default.")
	ca.fs.StringVar(&ca.DownstreamAddress.Account, PrefixDownstreamClusterAddr+"account", "root", "Database account of the primary TiDB Cluster, 'root' as default.")
	ca.fs.StringVar(&ca.DownstreamAddress.Password, PrefixDownstreamClusterAddr+"password", "", "Host address of the primary TiDB Cluster, '' as default.")

	return ca
}

type MakeupDownstreamCommandCtx struct {
	ClusterMigrationSubCommandCtx
}

func (mdc *MakeupDownstreamCommandCtx) makeupDBAccounts() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupSchemas() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupGlobalVariabls() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupConfigurations() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupStatistics() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupAutoIncrementalID() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupPlacementRules() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupSQLBindings() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) makeupAll() error {
	return nil
}

func (mdc *MakeupDownstreamCommandCtx) Name() string {
	return mdc.fs.Name()
}

func (mdc *MakeupDownstreamCommandCtx) Init(args []string) error {
	return mdc.fs.Parse(args)
}

func (mdc *MakeupDownstreamCommandCtx) Execute() error {
	return mdc.MakeupDownstreamCommandMain()
}

func (mdc *MakeupDownstreamCommandCtx) MakeupDownstreamCommandMain() (err error) {
	mdc.PrimaryDBConnPool, err = dbctrl.NewDBConnInfoByAdd(&mdc.PrimaryAddress)
	if err != nil {
		return err
	}

	mdc.PrimaryDBConn, err = mdc.PrimaryDBConnPool.Connect()
	if err != nil {
		return err
	}
	defer mdc.PrimaryDBConn.Close()

	switch mdc.CommandTarget {
	case CommandTargetAll:
		return mdc.makeupAll()
	case CommandTargetDBAccount:
		return mdc.makeupDBAccounts()
	case CommandTargetSchema:
		return mdc.makeupSchemas()
	case CommandTargetGlobalVariable:
		return mdc.makeupGlobalVariabls()
	case CommandTargetConfiguration:
		return mdc.makeupConfigurations()
	case CommandTargetPlacementRule:
		return mdc.makeupPlacementRules()
	case CommandTargetSQLBinding:
		return mdc.makeupPlacementRules()
	default:
		return nil
	}
}
