package routing_test

import (
	"testing"

	"github.com/stretchr/testify/assert"

	"github.com/veylant/ia-gateway/internal/pii"
	"github.com/veylant/ia-gateway/internal/routing"
)

func entity(typ string) pii.Entity { return pii.Entity{EntityType: typ} }

func TestScoreFromEntities_NoEntities_ReturnsNone(t *testing.T) {
	assert.Equal(t, routing.SensitivityNone, routing.ScoreFromEntities(nil))
	assert.Equal(t, routing.SensitivityNone, routing.ScoreFromEntities([]pii.Entity{}))
}

func TestScoreFromEntities_IBAN_ReturnsCritical(t *testing.T) {
	assert.Equal(t, routing.SensitivityCritical, routing.ScoreFromEntities([]pii.Entity{entity("IBAN")}))
}

func TestScoreFromEntities_CreditCard_ReturnsCritical(t *testing.T) {
	assert.Equal(t, routing.SensitivityCritical, routing.ScoreFromEntities([]pii.Entity{entity("CREDIT_CARD")}))
}

func TestScoreFromEntities_FRSSN_ReturnsCritical(t *testing.T) {
	assert.Equal(t, routing.SensitivityCritical, routing.ScoreFromEntities([]pii.Entity{entity("FR_SSN")}))
}

func TestScoreFromEntities_Person_ReturnsHigh(t *testing.T) {
	assert.Equal(t, routing.SensitivityHigh, routing.ScoreFromEntities([]pii.Entity{entity("PERSON")}))
}

func TestScoreFromEntities_Email_ReturnsMedium(t *testing.T) {
	assert.Equal(t, routing.SensitivityMedium, routing.ScoreFromEntities([]pii.Entity{entity("EMAIL")}))
}

func TestScoreFromEntities_UnknownType_ReturnsLow(t *testing.T) {
	assert.Equal(t, routing.SensitivityLow, routing.ScoreFromEntities([]pii.Entity{entity("CUSTOM_PII")}))
}

func TestScoreFromEntities_MixedEntities_ReturnsMax(t *testing.T) {
	entities := []pii.Entity{entity("EMAIL"), entity("PERSON"), entity("IBAN")}
	assert.Equal(t, routing.SensitivityCritical, routing.ScoreFromEntities(entities))
}

func TestSensitivity_String(t *testing.T) {
	cases := []struct{ s routing.Sensitivity; want string }{
		{routing.SensitivityNone, "none"},
		{routing.SensitivityLow, "low"},
		{routing.SensitivityMedium, "medium"},
		{routing.SensitivityHigh, "high"},
		{routing.SensitivityCritical, "critical"},
	}
	for _, tc := range cases {
		assert.Equal(t, tc.want, tc.s.String())
	}
}

func TestParseSensitivity_ValidValues(t *testing.T) {
	for _, name := range []string{"none", "low", "medium", "high", "critical"} {
		s, ok := routing.ParseSensitivity(name)
		assert.True(t, ok, "should parse %q", name)
		assert.Equal(t, name, s.String())
	}
}

func TestParseSensitivity_InvalidValue_ReturnsFalse(t *testing.T) {
	_, ok := routing.ParseSensitivity("unknown")
	assert.False(t, ok)
}
