// Copyright IBM Corp. 2016, 2025
// SPDX-License-Identifier: MPL-2.0

package api

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/stretchr/testify/require"
)

// TestSys_BillingOverview tests the BillingOverview API client method and structure of the response
func TestSys_BillingOverview(t *testing.T) {
	mockVaultServer := httptest.NewServer(http.HandlerFunc(mockVaultBillingHandler))
	defer mockVaultServer.Close()

	// Create API client pointing to mock server
	cfg := DefaultConfig()
	cfg.Address = mockVaultServer.URL
	client, err := NewClient(cfg)
	require.NoError(t, err)

	resp, err := client.Sys().BillingOverview(false)
	require.NoError(t, err)
	require.NotNil(t, resp)

	// Verify we have 2 months (current and previous)
	require.Len(t, resp.Months, 2)

	// Verify current month structure
	currentMonth := resp.Months[0]
	require.Equal(t, "2026-01", currentMonth.Month)
	require.Equal(t, "2026-01-14T10:49:00Z", currentMonth.UpdatedAt)
	require.Len(t, currentMonth.UsageMetrics, 9, "should have all 9 metrics")

	// Create a map to verify all expected metrics are present
	metricsMap := make(map[string]UsageMetric)
	for _, metric := range currentMonth.UsageMetrics {
		metricsMap[metric.MetricName] = metric
	}

	// Verify all expected metrics are present
	expectedMetrics := []string{
		"static_secrets",
		"dynamic_roles",
		"auto_rotated_roles",
		"kmip",
		"external_plugins",
		"data_protection_calls",
		"pki_units",
		"managed_keys",
		"ssh_units",
	}

	for _, metricName := range expectedMetrics {
		metric, exists := metricsMap[metricName]
		require.True(t, exists, "metric %s should be present", metricName)
		require.NotNil(t, metric.MetricData, "metric_data should not be nil for %s", metricName)
	}

	// Verify specific metric structures
	staticSecretsMetric := metricsMap["static_secrets"]
	require.Contains(t, staticSecretsMetric.MetricData, "total")
	require.Contains(t, staticSecretsMetric.MetricData, "metric_details")

	kmipMetric := metricsMap["kmip"]
	require.Contains(t, kmipMetric.MetricData, "used_in_month")
	require.Equal(t, true, kmipMetric.MetricData["used_in_month"])

	pkiMetric := metricsMap["pki_units"]
	require.Contains(t, pkiMetric.MetricData, "total")

	managedKeysMetric := metricsMap["managed_keys"]
	require.Contains(t, managedKeysMetric.MetricData, "total")
	require.Contains(t, managedKeysMetric.MetricData, "metric_details")

	// Verify previous month structure
	previousMonth := resp.Months[1]
	require.Equal(t, "2025-12", previousMonth.Month)
	require.Equal(t, "2025-12-31T23:59:59Z", previousMonth.UpdatedAt)
	require.Len(t, previousMonth.UsageMetrics, 1)

	// Verify external_plugins metric in previous month
	externalPluginsMetric := previousMonth.UsageMetrics[0]
	require.Equal(t, "external_plugins", externalPluginsMetric.MetricName)
	require.NotNil(t, externalPluginsMetric.MetricData)
	require.Contains(t, externalPluginsMetric.MetricData, "total")

	sshMetric := metricsMap["ssh_units"]
	require.Contains(t, sshMetric.MetricData, "total")
	require.Contains(t, sshMetric.MetricData, "metric_details")
}

func mockVaultBillingHandler(w http.ResponseWriter, _ *http.Request) {
	_, _ = w.Write([]byte(billingOverviewResponse))
}

const billingOverviewResponse = `{
  "request_id": "d8d3e6e1-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 0,
  "data": {
    "months": [
      {
        "month": "2026-01",
        "updated_at": "2026-01-14T10:49:00Z",
        "usage_metrics": [
          {
            "metric_name": "static_secrets",
            "metric_data": {
              "total": 10,
              "metric_details": [
                {
                  "type": "kv",
                  "count": 10
                }
              ]
            }
          },
          {
            "metric_name": "dynamic_roles",
            "metric_data": {
              "total": 15,
              "metric_details": [
                {
                  "type": "aws_dynamic",
                  "count": 5
                },
                {
                  "type": "azure_dynamic",
                  "count": 5
                },
                {
                  "type": "database_dynamic",
                  "count": 5
                }
              ]
            }
          },
          {
            "metric_name": "auto_rotated_roles",
            "metric_data": {
              "total": 10,
              "metric_details": [
                {
                  "type": "aws_static",
                  "count": 5
                },
                {
                  "type": "azure_static",
                  "count": 5
                }
              ]
            }
          },
          {
            "metric_name": "kmip",
            "metric_data": {
              "used_in_month": true
            }
          },
          {
            "metric_name": "external_plugins",
            "metric_data": {
              "total": 3
            }
          },
          {
            "metric_name": "data_protection_calls",
            "metric_data": {
              "total": 100,
              "metric_details": [
                {
                  "type": "transit",
                  "count": 50
                },
                {
                  "type": "transform",
                  "count": 50
                }
              ]
            }
          },
          {
            "metric_name": "pki_units",
            "metric_data": {
              "total": 100.5
            }
          },
          {
            "metric_name": "managed_keys",
            "metric_data": {
              "total": 10,
              "metric_details": [
                {
                  "type": "totp",
                  "count": 5
                },
				{
				  "type": "kmse",
				  "count": 5
				}
              ]
            }
          },
          {
            "metric_name": "ssh_units",
            "metric_data": {
              "total": 8.4,
              "metric_details": [
                {
                  "type": "otp_units",
                  "count": 5
                },
				{
				  "type": "certificate_units",
				  "count": 3.4
				}
			  ]
            }
          }
        ]
      },
      {
        "month": "2025-12",
        "updated_at": "2025-12-31T23:59:59Z",
        "usage_metrics": [
          {
            "metric_name": "external_plugins",
            "metric_data": {
              "total": 5
            }
          }
        ]
      }
    ]
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}`
