package provider

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-api/controllers/utils"
	"github.com/tidbcloud/infra-api/pkg/consts"
	"github.com/tidbcloud/infra-api/pkg/nodegroup"

	"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
	NodeGroupCreated = "CreateCdcNodeGroup"
	NodeGroupDeleted = "DeleteCdcNodeGroup"
)

var errUnimplemented = fmt.Errorf("provider unimplemented")

var _ Provider = &Unimplemented{}

func NewUnimplemented() *Unimplemented {
	return &Unimplemented{}
}

type Unimplemented struct {
}

func (p *Unimplemented) BuildBackup(backup *cloudv1.Backup, cluster *cloudv1.Cluster) (*v1alpha1.Backup, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) GetBackupClient(ctx context.Context, cluster *cloudv1.Backup) (client.Client, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) GetBackupNamespace(context.Context, *cloudv1.Backup) (string, error) {
	return "", errUnimplemented
}

func (p *Unimplemented) BuildRestore(restore *cloudv1.Restore, cluster *cloudv1.Cluster) (*v1alpha1.Restore, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) PostRestoreFinished(ctx context.Context, restore *cloudv1.Restore) error {
	return nil
}

func (p *Unimplemented) GetClient(ctx context.Context, cluster *cloudv1.Cluster) (client.Client, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) GetKubernetesStatus(cluster *cloudv1.Cluster) (*cloudv1.KubernetesStatus, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) GetComponentNodeLabels(componentType cloudv1.ComponentType) map[string]string {
	return map[string]string{}
}

func (p *Unimplemented) GetComponentPodLabels(componentType cloudv1.ComponentType) map[string]string {
	return map[string]string{}
}

func (p *Unimplemented) GetNodeZoneFromLabels(_ map[string]string) string {
	return ""
}

func (p *Unimplemented) GetNodeInstanceTypeFromLabels(_ map[string]string) string {
	return ""
}

func (p *Unimplemented) Overlay(*v1alpha1.TidbCluster) error {
	return errUnimplemented
}

func (p *Unimplemented) GetCdcUpstreamClient(context.Context, *cloudv1.TiCDC) (client.Client, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) GetCdcClient(context.Context, *cloudv1.Network) (client.Client, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) GetCdcKubernetesStatus(*cloudv1.Cluster) (*cloudv1.KubernetesStatus, error) {
	return nil, errUnimplemented
}

func (p *Unimplemented) CreateCdcNodeGroup(ctx context.Context, network *cloudv1.TiCDC, ngs *nodegroup.Set) (map[string]string, error) {
	// do nothing
	if utils.InIntegrationTest() {
		os.Setenv("CreateCdcNodeGroup", "true")
	}
	return map[string]string{}, nil
}

func (p *Unimplemented) DeleteCdcNodeGroup(ctx context.Context, network *cloudv1.TiCDC, ngs *nodegroup.Set) error {
	// do nothing
	if utils.InIntegrationTest() {
		os.Setenv("DeleteCdcNodeGroup", "true")
	}
	return nil
}

func (p *Unimplemented) RequireV1CertManager() bool {
	return false
}

func (p *Unimplemented) CertificateOptions() (kind string, name string, d time.Duration) {
	return consts.AwsPcaIssuerKind, consts.AwsPcaIssuer, consts.CertificateDuration
}

func (p *Unimplemented) OverrideImage(cluster *cloudv1.Cluster, imageName string) string {
	return imageName
}

func (p *Unimplemented) GetNetworkProxyBaseURL(_ context.Context, network *cloudv1.Network) (string, error) {
	return "", errUnimplemented
}
