package log_agent

import (
	"context"
	"fmt"

	"github.com/pingcap/errors"
	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-api/pkg/consts"
	"github.com/tidbcloud/infra-api/pkg/o11y"
)

const (
	loggingNamespace = "logging"
)

func AddO11yIDToNetwork(c *cloudv1.Network, o11yID string) {
	if c.Annotations == nil {
		c.Annotations = make(map[string]string)
	}
	c.Annotations[consts.O11yIDAnnotationKey] = o11yID
}

func GetLogStorageInfo(storages []o11y.StorageInfo) (bucket string, err error) {
	for _, storage := range storages {
		if storage.Category == o11y.LOGS {
			return storage.BucketName, nil
		}
	}
	return "", errors.New("no log storage found")
}

// tenantID fallbacks to "unknown", projectID fallbacks to "network.name"
func GetIDsFromNetworkCRD(n *cloudv1.Network) (tenantID, projectID string) {
	if v, ok := n.Labels[consts.ProjectTagKey]; ok && v != "" {
		projectID = v
	} else {
		projectID = fmt.Sprintf("%s", n.Name)
	}
	if v, ok := n.Labels[consts.TenantTagKey]; ok && v != "" {
		tenantID = v
	} else {
		tenantID = o11y.DefaultTenantLabelValue
	}
	return tenantID, projectID
}

func EnsureLoggingNamespace(ctx context.Context, shootClient client.Client) error {
	ns := corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: loggingNamespace}}
	err := shootClient.Create(ctx, &ns)
	if err != nil && !apierrors.IsAlreadyExists(err) {
		return errors.Annotate(err, "failed to create logging namespace")
	}
	return nil
}
