package store

import (
	"testing"
	"time"
)

func TestEffectiveModelRateLimitPolicyTreatsModelRulesAsAuthoritative(t *testing.T) {
	policy := EffectiveRateLimitPolicy(EffectiveRateLimitPolicyInput{
		PlatformPolicy: map[string]any{"rules": []any{
			map[string]any{"metric": "rpm", "limit": 500},
			map[string]any{"metric": "tpm_total", "limit": 100000},
		}},
		RuntimePolicy: map[string]any{"rules": []any{
			map[string]any{"metric": "rpm", "limit": 120},
			map[string]any{"metric": "tpm_total", "limit": 240000},
			map[string]any{"metric": "concurrent", "limit": 6},
		}},
		RuntimePolicyExplicit: true,
		ModelPolicy: map[string]any{"rules": []any{
			map[string]any{"metric": "rpm", "limit": 30},
			map[string]any{"metric": "concurrent", "limit": 2},
		}},
		ModelPolicyMode: "override",
	})

	if got := rateLimitForMetric(policy, "rpm"); got != 30 {
		t.Fatalf("expected model rpm limit to win, got %v", got)
	}
	if got := rateLimitForMetric(policy, "concurrent"); got != 2 {
		t.Fatalf("expected model concurrent limit to win, got %v", got)
	}
	if got := rateLimitForMetric(policy, "tpm_total"); got != 0 {
		t.Fatalf("expected missing model tpm limit to mean unlimited, got %v", got)
	}
}

func TestEffectiveModelRateLimitPolicyTreatsEmptyRuntimePolicyAsUnlimited(t *testing.T) {
	policy := EffectiveRateLimitPolicy(EffectiveRateLimitPolicyInput{
		PlatformPolicy: map[string]any{"rules": []any{
			map[string]any{"metric": "rpm", "limit": 500},
			map[string]any{"metric": "tpm_total", "limit": 100000},
		}},
		RuntimePolicy:         map[string]any{"rules": []any{}},
		RuntimePolicyExplicit: true,
		ModelPolicyMode:       "inherit",
	})

	if got := rateLimitForMetric(policy, "rpm"); got != 0 {
		t.Fatalf("expected empty runtime policy rpm to mean unlimited, got %v", got)
	}
	if got := rateLimitForMetric(policy, "tpm_total"); got != 0 {
		t.Fatalf("expected empty runtime policy tpm to mean unlimited, got %v", got)
	}
}

func TestEffectiveModelRateLimitPolicyTreatsNegativeLimitAsUnlimited(t *testing.T) {
	policy := EffectiveRateLimitPolicy(EffectiveRateLimitPolicyInput{
		PlatformPolicy: map[string]any{"rules": []any{
			map[string]any{"metric": "rpm", "limit": 500},
		}},
		RuntimePolicy: map[string]any{"rules": []any{
			map[string]any{"metric": "rpm", "limit": -1},
		}},
		RuntimePolicyExplicit: true,
		ModelPolicyMode:       "inherit",
	})

	if got := rateLimitForMetric(policy, "rpm"); got != -1 {
		t.Fatalf("expected negative runtime rpm marker to be preserved, got %v", got)
	}
	status := metricStatus(10, 10, 0, rateLimitForMetric(policy, "rpm"), "")
	if status.Limited {
		t.Fatalf("expected negative runtime rpm marker to be reported as unlimited, got %+v", status)
	}
}

func TestPriorityDemotionRecordFromEventPayloadKeepsReason(t *testing.T) {
	createdAt := time.Date(2026, 5, 12, 9, 30, 0, 0, time.UTC)
	record := priorityDemotionRecordFromEventPayload("event-1", "task-1", "fallback message", map[string]any{
		"platformId":      "platform-1",
		"platformModelId": "platform-model-1",
		"reason":          "priority_demote_policy",
		"errorCode":       "rate_limit",
		"errorMessage":    "upstream 429 rate limit",
		"category":        "rate_limit",
		"statusCode":      float64(429),
		"policySource":    "gateway_runner_policies.priority_demote_policy",
		"policy":          "priorityDemotePolicy",
		"policyRule":      "categories",
		"matchedValue":    "rate_limit",
		"dynamicPriority": float64(1511),
	}, createdAt)

	if record.Reason != "priority_demote_policy" || record.ErrorMessage != "upstream 429 rate limit" {
		t.Fatalf("expected demotion reason and error message to survive, got %+v", record)
	}
	if record.StatusCode != 429 || record.DynamicPriority != 1511 {
		t.Fatalf("expected numeric demotion metadata, got %+v", record)
	}
	if !record.CreatedAt.Equal(createdAt) {
		t.Fatalf("expected createdAt %s, got %s", createdAt, record.CreatedAt)
	}
}

func TestPlatformPolicyEventFromPayloadUsesAttemptErrorMessage(t *testing.T) {
	createdAt := time.Date(2026, 5, 12, 10, 30, 0, 0, time.UTC)
	record := platformPolicyEventFromPayload("event-1", "task-1", "task.policy.failover_disabled", "fallback event message", "upstream invalid api key", map[string]any{
		"platformId":      "platform-1",
		"platformModelId": "platform-model-1",
		"reason":          "failover_allow_policy",
		"errorCode":       "auth_failed",
		"category":        "auth_error",
		"statusCode":      float64(401),
		"policySource":    "gateway_runner_policies.failover_policy",
		"policy":          "failoverPolicy",
		"policyRule":      "allowCategories",
		"matchedValue":    "auth_error",
	}, createdAt)

	if record.EventType != "task.policy.failover_disabled" || record.Reason != "failover_allow_policy" {
		t.Fatalf("expected disabled event identity to survive, got %+v", record)
	}
	if record.ErrorMessage != "upstream invalid api key" || record.StatusCode != 401 {
		t.Fatalf("expected disabled reason details from attempt, got %+v", record)
	}
}
