//go:build e2e
// +build e2e

package utils

import (
	"fmt"
	"io"
	"net/http"
	"testing"

	"github.com/tidbcloud/observability/pkg/common/message"
	"github.com/tidbcloud/observability/pkg/common/structs"
)

func CheckServerlessExternalMetricsRoute(t *testing.T, cluster *structs.ObservabilityCluster) error {
	s := GetService()

	// Build the external metrics path
	metricsPath := fmt.Sprintf("/external/metrics/%s/tenant/%s/project/%s/application/%s/api/v1/query",
		cluster.BizType,
		cluster.TenantID,
		cluster.ProjectID,
		cluster.ApplicationID,
	)

	// Call auth route API to validate the path and get VM routing info
	authURL := fmt.Sprintf("%s%s/auth/?path=%s",
		s.RegionalURL,
		ApiPrefix,
		metricsPath,
	)

	request, err := http.NewRequest("GET", authURL, nil)
	if err != nil {
		return fmt.Errorf("failed to create auth request: %w", err)
	}

	// Execute request
	resp, err := http.DefaultClient.Do(request)
	if err != nil {
		return fmt.Errorf("failed to execute auth request: %w", err)
	}
	defer resp.Body.Close()

	// Check response status
	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("auth route check failed with status %d, body: %s", resp.StatusCode, string(body))
	}

	// Parse response to verify VM routing info is returned
	respContent, err := io.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("failed to read auth response: %w", err)
	}

	var authResp message.AuthRouteResp
	err = UnmarshalRespData(respContent, &authResp)
	if err != nil {
		return fmt.Errorf("failed to unmarshal auth response: %w", err)
	}

	// Verify VM routing info is present
	if authResp.VMAccountID == 0 || authResp.VMProjectID == 0 || authResp.VMClusterName == "" {
		return fmt.Errorf("invalid VM routing info: accountID=%d, projectID=%d, clusterName=%s",
			authResp.VMAccountID, authResp.VMProjectID, authResp.VMClusterName)
	}

	return nil
}

func CheckServerlessInternalMetricsRoute(t *testing.T, cluster *structs.ObservabilityCluster) error {
	s := GetService()

	// Build the internal metrics URL using cluster ID
	// Pattern: /internal/metrics/<cluster_id>/api/v1/query?query=up
	internalURL := fmt.Sprintf("%s/internal/metrics/%s/api/v1/query?query=up",
		s.DsURL,
		cluster.ID,
	)

	request, err := http.NewRequest("GET", internalURL, nil)
	if err != nil {
		return fmt.Errorf("failed to create internal metrics request %s: %w", internalURL, err)
	}

	// Execute request
	resp, err := http.DefaultClient.Do(request)
	if err != nil {
		return fmt.Errorf("failed to execute internal metrics request %s : %w", internalURL, err)
	}
	defer resp.Body.Close()

	// Check response status - should be 2xx
	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
		body, _ := io.ReadAll(resp.Body)
		return fmt.Errorf("internal metrics check %s failed with status %d, body: %s", internalURL, resp.StatusCode, string(body))
	}

	return nil
}
