package clusterproxy

import (
	"context"
	"encoding/json"

	"github.com/tidbcloud/pkgv2/clusterproxy"

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

type fakeClusterProxyProviderImp struct{}

func NewFakeClusterProxyProvider() Provider {
	return &fakeClusterProxyProviderImp{}
}

func (c *fakeClusterProxyProviderImp) GetClusterProxy(
	ctx context.Context,
	clusterID uint64,
	proxyBaseUrl, tidbVersion string,
	proxyOp *clusterproxy.ClusterOperator,
) (ClusterProxy, bizerr.BizError) {
	if proxyBaseUrl == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "cluster ProxyEndpoint is empty")
	}
	if tidbVersion == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "cluster version is empty")
	}

	return &fakeClusterProxyImp{
		operator: proxyOp,
	}, nil
}

type fakeClusterProxyImp struct {
	operator *clusterproxy.ClusterOperator
}

func (p *fakeClusterProxyImp) SetOperator(operator *clusterproxy.ClusterOperator) bizerr.BizError {
	if operator.Username == "" {
		return bizerr.New(bizerr.ErrCodeUnknown, "username is empty")
	}
	if operator.AuthMethod == clusterproxy.AuthMethodToken {
		return bizerr.New(bizerr.ErrCodeUnknown, "only support token auth")
	}
	p.operator = operator
	return nil
}

func (p *fakeClusterProxyImp) ExecuteSQL(ctx context.Context, sql string) bizerr.BizError {
	if sql == "" {
		return bizerr.New(bizerr.ErrCodeUnknown, "sql is empty")
	}
	return nil
}

func (p *fakeClusterProxyImp) ExecuteMultiSQL(ctx context.Context, sqls []string) bizerr.BizError {
	if len(sqls) == 0 {
		return bizerr.New(bizerr.ErrCodeUnknown, "sqls is empty")
	}
	return nil
}

func (p *fakeClusterProxyImp) InitCloudAdminPassword(ctx context.Context, cloudAdminPwd string) bizerr.BizError {
	if cloudAdminPwd == "" {
		return bizerr.New(bizerr.ErrCodeUnknown, "cloudAdminPwd is empty")
	}
	return nil
}

func (p *fakeClusterProxyImp) ChangePassword(ctx context.Context, username, newPwd string) bizerr.BizError {
	if username == "" {
		return bizerr.New(bizerr.ErrCodeUnknown, "username is empty")
	}
	return nil
}

type ReplicaModel struct {
	Replicas []uint32 `json:"MAX(REPLICA_COUNT)"`

	Type     []string `json:"Type"`
	Instance []string `json:"Instance"`
	Name     []string `json:"Name"`
	Value    []string `json:"Value"`
}

func (p *fakeClusterProxyImp) QuerySQL(ctx context.Context, sql string) ([]byte, bizerr.BizError) {
	if sql == "" {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "sql is empty")
	}

	m := ReplicaModel{
		Replicas: []uint32{0},
		Value:    []string{"Ni4w", "Ni4w"},
	}

	data, err := json.Marshal(m)
	if err != nil {
		return nil, bizerr.WrapError(err, "marshal failed")
	}
	return data, nil
}

func (p *fakeClusterProxyImp) AuditLogCheck(
	_ context.Context,
	_ *AuditCheckModel,
) (bool, bizerr.BizError) {
	return true, nil
}
