package resource

import (
	"strconv"
	"time"

	"github.com/pingcap/test-infra/sdk/core"
)

var (
	DMMasterContainerName = "dm-master"
	DMWorkerContainerName = "dm-worker"
)

const (
	_ DMCompType = iota
	DMMaster
	DMWorker
)

type DMCompType int

func (d DMCompType) String() string {
	switch d {
	case DMMaster:
		return "master"
	case DMWorker:
		return "worker"
	default:
		return "#" + strconv.Itoa(int(d))
	}
}

// DMCluster is the dm cluster interface
type DMCluster interface {
	core.Resource
	Exec(podName, containerName string, cmd ...string) (stdout string, stderr string, exitCode int, err error)
	Upgrade(opts DMClusterUpgradeOptions) error
	ChaosClient() ChaosClient
	ChaosSelect(selector DMClusterSelectorOpts) ([]ChaosSelector, error)
}

// DMExecOptions wraps a command which wants to execute to current dm master
type DMExecOptions struct {
	Command string
}

// DMClusterUpgradeOptions wraps a version wants to upgrade to on target component node
type DMClusterUpgradeOptions struct {
	// Version is like: v5.2.0 style or release-5.0, master, nightly etc.
	// For TiUP, only the Version field is needed
	Version string
	// Timeout wait for scaling, a timeout of 0 is interpreted as an infinity
	Timeout time.Duration
}

// DMClusterSelectorOpts specifies how to filter the dm cluster instances.
type DMClusterSelectorOpts struct {
	*DMClusterMasterSelectorSpec
	*DMClusterWorkerSelectorSpec
}

// DMClusterMasterSelectorSpec specifies how to filter the dm-master instances.
//
// Note that can only set one field one time
//
// For example, to select the first instance:
//  Peer: 0
// Or select alls:
//  All: true
type DMClusterMasterSelectorSpec struct {
	Peer *int
	All  bool
}

// DMClusterWorkerSelectorSpec specifies how to filter the dm-worker instances.
//
// Note that can only set one field one time
//
// For example, to select the first instance:
//  Peer: 0
// Or select alls:
//  All: true
type DMClusterWorkerSelectorSpec struct {
	Peer *int
	All  bool
}
