package infraapi

import (
	"context"
	"fmt"

	"github.com/pingcap/errors"
	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
)

func TicdcName(clusterID uint64) string {
	return fmt.Sprintf("%d-ticdc", clusterID)
}

// CreateTicdcIgnoreExist create the ticdc and ignore already exist error.
// CreateTicdcIgnoreExist Will set ns/name according projectID and clusterID.
func (a *API) CreateTicdcIgnoreExist(ctx context.Context, projectID uint64, clusterID uint64, cr *cloudv1.TiCDC) error {
	ns := Namespace(a.projectName, projectID)
	name := TicdcName(clusterID)
	cr.Namespace = ns
	cr.Name = name

	err := a.client.Create(ctx, cr)
	if err != nil {
		if apierrors.IsAlreadyExists(err) {
			return nil
		}
		return errors.AddStack(err)
	}

	return nil
}

// UpdateTicdc update the ticdc get by GetTicdc().
func (a *API) UpdateTicdc(ctx context.Context, d *cloudv1.TiCDC) error {
	err := a.client.Update(ctx, d)
	if err != nil {
		return errors.AddStack(err)
	}
	return nil
}

func (a *API) DeleteTicdcIfExist(ctx context.Context, projectID uint64, clusterID uint64) error {
	ns := Namespace(a.projectName, projectID)
	name := TicdcName(clusterID)
	d := &cloudv1.TiCDC{
		ObjectMeta: metav1.ObjectMeta{Namespace: ns, Name: name},
	}

	err := a.client.Delete(ctx, d)
	if err != nil {
		if apierrors.IsNotFound(err) {
			return nil
		}
		return errors.AddStack(err)
	}
	return nil
}

// GetTicdc get cdc CR for the cluster.
func (a *API) GetTicdc(ctx context.Context, projectID, clusterID uint64) (*cloudv1.TiCDC, error) {
	var (
		err   error
		ticdc cloudv1.TiCDC
		ns    = Namespace(a.projectName, projectID)
		name  = TicdcName(clusterID)
	)
	err = a.client.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, &ticdc)
	if err != nil {
		return nil, err
	}
	return &ticdc, nil
}
