package providers

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gopkg.in/yaml.v3"
)

type verifyWrapper struct {
	Verify VerifySpec `yaml:"verify"`
}

func TestVerifySpec_NewFieldsParse(t *testing.T) {
	y := `
verify:
  method: POST
  url: https://api.example.com/v1/models
  headers:
    Authorization: "Bearer {{KEY}}"
  body: '{"api_key":"{{KEY}}"}'
  success_codes: [200, 201]
  failure_codes: [401, 403]
  rate_limit_codes: [429, 529]
  metadata_paths:
    org: organization.name
    tier: rate_limit.tier
`
	var w verifyWrapper
	require.NoError(t, yaml.Unmarshal([]byte(y), &w))

	assert.Equal(t, "POST", w.Verify.Method)
	assert.Equal(t, `{"api_key":"{{KEY}}"}`, w.Verify.Body)
	assert.Equal(t, []int{200, 201}, w.Verify.SuccessCodes)
	assert.Equal(t, []int{401, 403}, w.Verify.FailureCodes)
	assert.Equal(t, []int{429, 529}, w.Verify.RateLimitCodes)
	assert.Equal(t, "organization.name", w.Verify.MetadataPaths["org"])
	assert.Equal(t, "rate_limit.tier", w.Verify.MetadataPaths["tier"])
}

func TestVerifySpec_LegacyFieldsStillWork(t *testing.T) {
	y := `
verify:
  method: GET
  url: https://api.example.com/v1/models
  valid_status: [200, 204]
  invalid_status: [401, 403, 404]
`
	var w verifyWrapper
	require.NoError(t, yaml.Unmarshal([]byte(y), &w))

	assert.Equal(t, []int{200, 204}, w.Verify.ValidStatus)
	assert.Equal(t, []int{401, 403, 404}, w.Verify.InvalidStatus)
	// Effective* should fall back to legacy when canonical fields are empty
	assert.Equal(t, []int{200, 204}, w.Verify.EffectiveSuccessCodes())
	assert.Equal(t, []int{401, 403, 404}, w.Verify.EffectiveFailureCodes())
	assert.Equal(t, []int{429}, w.Verify.EffectiveRateLimitCodes())
}

func TestVerifySpec_Defaults(t *testing.T) {
	var v VerifySpec
	assert.Equal(t, []int{200}, v.EffectiveSuccessCodes())
	assert.Equal(t, []int{401, 403}, v.EffectiveFailureCodes())
	assert.Equal(t, []int{429}, v.EffectiveRateLimitCodes())
}

func TestVerifySpec_CanonicalFieldsPreferred(t *testing.T) {
	v := VerifySpec{
		SuccessCodes:   []int{201},
		FailureCodes:   []int{400},
		RateLimitCodes: []int{503},
		ValidStatus:    []int{200},
		InvalidStatus:  []int{401},
	}
	assert.Equal(t, []int{201}, v.EffectiveSuccessCodes())
	assert.Equal(t, []int{400}, v.EffectiveFailureCodes())
	assert.Equal(t, []int{503}, v.EffectiveRateLimitCodes())
}
