package shared

import (
	"reflect"
	"testing"

	"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
)

func TestReferenceMediaTypesReturnsDefensiveCopy(t *testing.T) {
	want := []string{
		"application/json",
		"application/x-yaml",
		"application/yaml",
		"text/markdown",
		"text/plain",
	}
	got := ReferenceMediaTypes()
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("ReferenceMediaTypes() = %#v, want %#v", got, want)
	}
	got[0] = "changed"
	if again := ReferenceMediaTypes(); again[0] != "application/json" {
		t.Fatalf("ReferenceMediaTypes() reused backing storage: %#v", again)
	}
}

func TestReferenceSlotsUseDescriptionsAndExpectedOrder(t *testing.T) {
	descriptions := ReferenceSlotDescriptions{
		Glossary: "Glossary reference",
		Party:    "Party reference",
		Players:  "Players reference",
		Roster:   "Roster reference",
	}
	got := ReferenceSlots(descriptions)
	want := []contracts.ReferenceSlot{
		{Name: "glossary", Description: descriptions.Glossary, AcceptedMediaTypes: ReferenceMediaTypes()},
		{Name: "party", Description: descriptions.Party, AcceptedMediaTypes: ReferenceMediaTypes()},
		{Name: "players", Description: descriptions.Players, AcceptedMediaTypes: ReferenceMediaTypes()},
		{Name: "roster", Description: descriptions.Roster, AcceptedMediaTypes: ReferenceMediaTypes()},
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("ReferenceSlots() = %#v, want %#v", got, want)
	}
}

func TestReferenceSlotsReturnDefensiveCopies(t *testing.T) {
	first := ReferenceSlots(ReferenceSlotDescriptions{})
	second := ReferenceSlots(ReferenceSlotDescriptions{})

	first[0].Name = "changed"
	first[0].AcceptedMediaTypes[0] = "changed"

	if second[0].Name != "glossary" {
		t.Fatalf("ReferenceSlots() reused slot slice: %#v", second)
	}
	if second[0].AcceptedMediaTypes[0] != "application/json" {
		t.Fatalf("ReferenceSlots() reused media type slice: %#v", second)
	}
}
