package resource

import (
	"context"
	"database/sql"
	"net/url"

	prometheus_api "github.com/prometheus/client_golang/api/prometheus/v1"

	apiresource "github.com/pingcap/test-infra/common/model/resource"
	"github.com/pingcap/test-infra/sdk/core"
)

type TiDBCloudImportDataFormat int64

const (
	TiDBCloudImportDataFormatSQL            = TiDBCloudImportDataFormat(1)
	TiDBCloudImportDataFormatAuroraSnapshot = TiDBCloudImportDataFormat(2)
)

type TiDBCloudCluster interface {
	core.Resource
	GetDB(dbName string) (db *sql.DB, err error)
	ServiceURL(typ TiDBAddrType) (*url.URL, error)
	GetSpec() apiresource.TiDBCloudClusterSpec
	GetStatus() (*apiresource.TiDBCloudClusterStatus, error)
	PrometheusAPI() (prometheus_api.API, error)
	Import(ctx context.Context, options TiDBCloudImportOptions) error
	Backup(ctx context.Context, opts TiDBCloudBackupOptions) (backupID string, err error)
	// Restore creates a new cluster then restores data into that cluster
	// (in contrast, InplaceRestore() will not create a new cluster before restoring data)
	Restore(ctx context.Context, opts TiDBCloudRestoreOptions) (TiDBCloudCluster, error)
	// InplaceRestore restores data into current cluster, without creating a new cluster
	// (in contrast, Restore() will create a new cluster before restoring data)
	InplaceRestore(ctx context.Context, opts TiDBCloudInplaceRestoreOptions) error
	// ResetCluster deletes all data of components(i.e. rm -rf data of tikv, pd...), then restarts cluster.
	// It's to simulate a fresh deployed cluster
	ResetCluster() error
	ChaosClient() ChaosClient
	ChaosSelect(selector TiDBClusterSelectorOpts) ([]ChaosSelector, error)
}

type TiDBCloudImportOptions struct {
	SourceURL  string
	DataFormat TiDBCloudImportDataFormat
	AwsRoleArn string
}

// TiDBCloudBackupOptions backup name should be unique
type TiDBCloudBackupOptions struct {
	BackupName string
}

// TiDBCloudRestoreOptions wraps only support override password here,
// and we will support to set the profile of restore cluster in future
type TiDBCloudRestoreOptions struct {
	ClusterName string
	BackupID    string
	Password    string
}

type TiDBCloudInplaceRestoreBackupType string

const (
	TiDBCloudInplaceRestoreBackupTypeFull  TiDBCloudInplaceRestoreBackupType = "full"
	TiDBCloudInplaceRestoreBackupTypeDB    TiDBCloudInplaceRestoreBackupType = "db"
	TiDBCloudInplaceRestoreBackupTypeTable TiDBCloudInplaceRestoreBackupType = "table"
	TiDBCloudInplaceRestoreBackupTypeRaw   TiDBCloudInplaceRestoreBackupType = "raw"
)

type TiDBCloudInplaceRestoreOptions struct {
	BackupType TiDBCloudInplaceRestoreBackupType
	DBName     *string
	TableName  *string

	BucketName   string
	ObjectPrefix string
}
