package provider

import (
	"context"
	"os"
	"time"

	storagev1 "k8s.io/api/storage/v1"
	"k8s.io/apimachinery/pkg/labels"
	"sigs.k8s.io/controller-runtime/pkg/client"

	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"
)

var _ Cdc = new(GardenerCDCProvider)

type GardenerCDCProvider struct {
}

func NewGardenerCDCProvider() Cdc {
	return &GardenerCDCProvider{}
}

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

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

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

func (c *GardenerCDCProvider) CreateCdcNodeGroup(ctx context.Context, cdc *cloudv1.TiCDC, cls *cloudv1.Cluster, ngs *nodegroup.Set) (map[string]string, error) {
	// do nothing
	if utils.InIntegrationTest() {
		os.Setenv("CreateCdcNodeGroup", "true")
	}
	return map[string]string{nodegroup.GardenerWorkerPrefixLabelName: ngs.Name}, nil
}

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

func (c *GardenerCDCProvider) ReleaseNodes(ctx context.Context, cr *cloudv1.TiCDC, ngNamePrefix string, labelSet labels.Set) error {
	return nil
}

func (p *GardenerCDCProvider) UpdateNodegroupTopology(ctx context.Context, cr *cloudv1.TiCDC, topology map[string]int) error {
	return nil
}

func (p *GardenerCDCProvider) SetResourceLabels(ctx context.Context, cr *cloudv1.TiCDC) error {
	return nil
}

func (p *GardenerCDCProvider) EnsureAllNodegroupsReady(ctx context.Context, cr *cloudv1.TiCDC) error {
	return nil
}

func (p *GardenerCDCProvider) GetNodegroupsByFilter(ctx context.Context, cr *cloudv1.TiCDC, selector labels.Selector) (map[string]int, error) {
	return nil, nil
}

func (p *GardenerCDCProvider) DeleteNodegroupsByFilter(ctx context.Context, cr *cloudv1.TiCDC, selector labels.Selector) error {
	return nil
}

func (c *GardenerCDCProvider) RequireV1CertManager() bool {
	return false
}

func (c *GardenerCDCProvider) Credentials(ctx context.Context, network *cloudv1.Network) ([]byte, error) {
	return nil, nil
}

func (c *GardenerCDCProvider) CertificateOptions(cluster *cloudv1.Cluster) (kind string, name string, group string, d time.Duration) {
	return consts.AwsPcaIssuerKind, consts.AwsPcaIssuer, consts.CertManagerGroup, consts.CertificateDuration
}

func (c *GardenerCDCProvider) OverrideImage(cluster *cloudv1.Cluster, imageName string) string {
	return imageName
}

func (c *GardenerCDCProvider) GetNetworkProxyBaseURL(_ context.Context, network *cloudv1.Network) (string, error) {
	networkStatus, err := cloudv1.GardenerNetworkStatusFromNetwork(network)
	if err != nil {
		return "", err
	}
	return networkStatus.ProxyBaseUrl, nil
}

func (c *GardenerCDCProvider) IsDPCompatMode() bool {
	// In gardener, the CR will only in api server,no need get CR from new path, so we always return false
	return false
}

func (c *GardenerCDCProvider) BuildStorageClass() *storagev1.StorageClass {
	return nil
}
