package common

import (
	"context"
	"fmt"

	"github.com/tidbcloud/eks-provider/controllers/network/task"
	"github.com/tidbcloud/infra-provider/pkg/config"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/helm"
	"github.com/tidbcloud/infra-provider/pkg/namer"
	"github.com/tidbcloud/infra-provider/pkg/o11y/log_agent"
)

const (
	lokiReleaseName      = "loki-fluentbit"
	clientCertSecretName = "client-auth-cert"
	filebeatReleaseName  = "filebeat"
)

// Loki collects the whole dataplane pod logs and send them to Loki in the base cluster.
// It's deployed as DaemonSet in the observability namespace.
type Loki struct {
	*task.BaseTask
	config *config.O11yAgentConfig
}

func NewLoki(ctx *task.Context) *Loki {
	return &Loki{
		BaseTask: &task.BaseTask{Context: ctx},
		config: &config.O11yAgentConfig{
			ReleaseName:   lokiReleaseName,
			Namespace:     task.ObservabilityNamespace,
			HelmChartPath: ctx.Config.Network.O11yConfig.LokiConfig.HelmChartPath,
			HelmValues: map[string]interface{}{
				"config": map[string]interface{}{
					// The label of the logging system should be consistent with the monitoring system
					"labels": fmt.Sprintf(`{cluster="%s-dataplane/%s"}`, ctx.Network.Spec.Provider, namer.LegacyBuildClusterNameByNetwork(ctx.Network)),
				},
				"enableTLS":            true,
				"clientAuthSecretName": clientCertSecretName,
				"loki": map[string]interface{}{
					// Old way: get loki 4th-layer clb (backed by nginx ingress with tls) dns name. The ingress is located in logging ns of base eks.
					// New way: hardcode dns name in provider's config.
					"serviceName":   ctx.Config.Network.O11yConfig.LokiServerDns,
					"servicePort":   443,
					"serviceScheme": "https",
					"servicePath":   `/loki/api/v1/push`,
				},
				"priorityClassName": log_agent.NodeCriticalPriorityClassName,
			},
		},
	}
}

var _ deploy.Task = (*Loki)(nil)

func (t *Loki) Name() string {
	return "Loki"
}

func (t *Loki) Create(ctx context.Context) deploy.Result {
	// Delete fluent-bit release.
	if err := helm.Uninstall(ctx, t.Remote, t.config, lokiReleaseName); err != nil {
		// Do not return, just log the error.
		t.Logger.Info("failed to uninstall fluent-bit release, maybe it's not installed, just ignore it")
	}
	// Delete legacy filebeat release.
	if err := helm.Uninstall(ctx, t.Remote, t.config, filebeatReleaseName); err != nil {
		// Do not return, just log the error.
		t.Logger.Info("failed to uninstall legacy filebeat release, maybe it's not installed, just ignore it")
	}

	return deploy.Done()
}

func (t *Loki) PostCreate(ctx context.Context) (res deploy.Result) {
	return deploy.Done()
}

func (t *Loki) Delete(_ context.Context) deploy.Result {
	return deploy.Done()
}

func (t *Loki) PostDelete(_ context.Context) deploy.Result {
	return deploy.Done()
}
