package service

import (
	"context"
	"errors"
	"fmt"

	corev1 "k8s.io/api/core/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
	nodeExporterNamespace = "monitoring"
	// nodeExporterInstanceKey / nodeExporterInstanceValue select by Helm release name.
	// The release name is "node-exporter" in every environment config (resources, gcp, azure).
	// This is stable regardless of nameOverride: without nameOverride the chart deploys with
	// app.kubernetes.io/name=prometheus-node-exporter; with nameOverride="node-exporter" it
	// deploys with app.kubernetes.io/name=node-exporter. The instance label is always the
	// release name and therefore invariant across both deployment variants.
	nodeExporterInstanceKey   = "app.kubernetes.io/instance"
	nodeExporterInstanceValue = "node-exporter"
	nodeExporterPortName      = "metrics"
)

var errNodeExporterListFailed = errors.New("node-exporter list failed")

func (s *AgentService) getNodeExporterPort(ctx context.Context, nodeName string) (int32, error) {
	var podList corev1.PodList
	if err := s.dataplaneCli.List(ctx, &podList,
		client.InNamespace(nodeExporterNamespace),
		client.MatchingLabels{
			nodeExporterInstanceKey: nodeExporterInstanceValue,
		},
		client.MatchingFields{"spec.nodeName": nodeName},
	); err != nil {
		return 0, fmt.Errorf("%w: on node %s: %w", errNodeExporterListFailed, nodeName, err)
	}

	var running []corev1.Pod
	for _, p := range podList.Items {
		if p.Status.Phase == corev1.PodRunning {
			running = append(running, p)
		}
	}
	if len(running) == 0 {
		return 0, fmt.Errorf("no running node-exporter pod found on node %s", nodeName)
	}
	if len(running) > 1 {
		return 0, fmt.Errorf("ambiguous: %d running node-exporter pods found on node %s", len(running), nodeName)
	}
	pod := running[0]
	for _, c := range pod.Spec.Containers {
		for _, p := range c.Ports {
			if p.Name == nodeExporterPortName {
				return p.ContainerPort, nil
			}
		}
	}
	return 0, fmt.Errorf("node-exporter pod on node %s has no port named %q", nodeName, nodeExporterPortName)
}
