package utils

import (
	"context"
	"errors"
	"fmt"
	"strconv"
	"strings"

	infra "github.com/tidbcloud/tidb-management-service/api/serverless_infra"
	infraclient "github.com/tidbcloud/tidb-management-service/api/serverless_infra/client"
	"github.com/tidbcloud/tidb-management-service/api/serverless_infra/meta"
)

const newNsPrefix = "cluster-"

// GetInfraCluster tries to get infra cluster by two ns formats: new format first, then old format.
// New format: {ENV}-cluster-{clusterId}; Old format: {ENV}-{projectId}.
func GetInfraCluster(
	ctx context.Context,
	infraClusterClient infraclient.Client,
	nsPrefix string,
	clusterId string,
	projectId uint64,
) (*infra.Cluster, error) {
	newNs := fmt.Sprintf("%s%s%s", nsPrefix, newNsPrefix, clusterId)
	cluster := &infra.Cluster{ObjectMeta: meta.ObjectMeta{Namespace: newNs, Name: clusterId}}
	err := infraClusterClient.Get(ctx, cluster)
	if errors.Is(err, infraclient.ErrNotFound) {
		oldNs := fmt.Sprintf("%s%d", nsPrefix, projectId)
		cluster = &infra.Cluster{ObjectMeta: meta.ObjectMeta{Namespace: oldNs, Name: clusterId}}
		err = infraClusterClient.Get(ctx, cluster)
	}
	return cluster, err
}

// ParseNamespacePrefixAndProjectID extracts "{ENV}-" and projectId from namespace.
// Supported formats: staging-{projectId}, prod-{projectId}, nightly-ms-{projectId}.
func ParseNamespacePrefixAndProjectID(ns string) (string, uint64, error) {
	items := strings.Split(ns, "-")
	// staging-{projectId} / prod-{projectId}
	if len(items) == 2 {
		projectId, err := strconv.ParseUint(items[1], 10, 64)
		if err != nil {
			return "", 0, fmt.Errorf("parse project id from namespace %q: %w", ns, err)
		}
		return items[0] + "-", projectId, nil
	}
	// nightly-ms-{projectId}
	if len(items) == 3 {
		projectId, err := strconv.ParseUint(items[2], 10, 64)
		if err != nil {
			return "", 0, fmt.Errorf("parse project id from namespace %q: %w", ns, err)
		}
		return items[0] + "-" + items[1] + "-", projectId, nil
	}
	return "", 0, fmt.Errorf("invalid namespace %q", ns)
}
