package clusterproxy

import (
	"context"

	"github.com/tidbcloud/pkgv2/clusterproxy"

	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

//go:generate go run go.uber.org/mock/mockgen@latest -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock_$GOPACKAGE/mock_$GOFILE
type ClusterProxy interface {
	SetOperator(operator *clusterproxy.ClusterOperator) bizerr.BizError

	ExecuteSQL(ctx context.Context, sql string) bizerr.BizError
	ExecuteMultiSQL(ctx context.Context, sqls []string) bizerr.BizError
	// InitCloudAdminPassword init password for cloud_admin. The cloud_admin account was created in tidb-initializer,
	// and one empty password has been set in this stage. When the cluster goes into launching phase, we need to change password
	// for cloud_admin for security. In this scenario, we use this method to make this change. In internal implement,
	// we connect tidb by cloud_admin with empty password then execute a 'ALTER USER' SQL to do this operation.
	InitCloudAdminPassword(ctx context.Context, cloudAdminPwd string) bizerr.BizError
	ChangePassword(ctx context.Context, username, newPwd string) bizerr.BizError
	QuerySQL(ctx context.Context, sql string) ([]byte, bizerr.BizError)
	// AuditLogCheck is for next-gen only, which uses service-proxy to do the check.
	AuditLogCheck(ctx context.Context, audtlogReq *AuditCheckModel) (bool, bizerr.BizError)
}

const SqlErrFormat = "sql err: %d %s"

// AuditCheckModel is copied from tidbcloud/cluster-service-ng/internal/service-proxy/pkg/checker/core/types.go
// to avoid import.
type AuditCheckModel struct {
	// TargetType should always be "audit".
	TargetType string       `json:"targetType"`
	Audit      *AuditParams `json:"audit,omitempty"`
}

type AuditParams struct {
	BucketURL string `json:"bucketUrl,omitempty"`
	Region    string `json:"region,omitempty"`

	AWS      *AWSAuth      `json:"aws,omitempty"`
	GCP      *GCPAuth      `json:"gcp,omitempty"`
	Azure    *AzureAuth    `json:"azure,omitempty"`
	AliCloud *AliCloudAuth `json:"alicloud,omitempty"`
}

type AWSAuth struct {
	RoleARN         string `json:"roleArn,omitempty"`
	ExternalID      string `json:"externalID,omitempty"`
	AccessKeyID     string `json:"access_key_id,omitempty"`
	SecretAccessKey string `json:"secret_access_key,omitempty"`
}

type GCPAuth struct {
	ServiceAccount string `json:"serviceAccount,omitempty"`
}

type AzureAuth struct {
	SASToken string `json:"sasToken,omitempty"`
	// ClientID is only used by the audit-log test-connection path when Azure falls back to kubelet identity auth.
	ClientID string `json:"clientId,omitempty"`
}

type AliCloudAuth struct {
	RoleARN         string `json:"roleArn,omitempty"`
	ExternalID      string `json:"externalID,omitempty"`
	RoleSessionName string `json:"roleSessionName,omitempty"`
}
