package tools

import (
	"testing"

	"git.warky.dev/wdevs/amcs/internal/mcperrors"
)

func TestErrRequiredFieldReturnsFieldMetadata(t *testing.T) {
	rpcErr, data := requireRPCError(t, errRequiredField("name"))
	if data.Type != mcperrors.TypeInvalidInput {
		t.Fatalf("errRequiredField() type = %q, want %q", data.Type, mcperrors.TypeInvalidInput)
	}
	if data.Field != "name" {
		t.Fatalf("errRequiredField() field = %q, want %q", data.Field, "name")
	}
	if data.Detail != "required" {
		t.Fatalf("errRequiredField() detail = %q, want %q", data.Detail, "required")
	}
	if rpcErr.Message != "name is required" {
		t.Fatalf("errRequiredField() message = %q, want %q", rpcErr.Message, "name is required")
	}
}

func TestErrInvalidFieldReturnsFieldMetadata(t *testing.T) {
	rpcErr, data := requireRPCError(t, errInvalidField("severity", "severity must be one of: low, medium, high, critical", "pass one of: low, medium, high, critical"))
	if data.Field != "severity" {
		t.Fatalf("errInvalidField() field = %q, want %q", data.Field, "severity")
	}
	if data.Detail != "invalid" {
		t.Fatalf("errInvalidField() detail = %q, want %q", data.Detail, "invalid")
	}
	if data.Hint == "" {
		t.Fatal("errInvalidField() hint = empty, want guidance")
	}
	if rpcErr.Message == "" {
		t.Fatal("errInvalidField() message = empty, want non-empty")
	}
}

func TestErrOneOfRequiredReturnsFieldsMetadata(t *testing.T) {
	rpcErr, data := requireRPCError(t, errOneOfRequired("content_base64", "content_uri"))
	if data.Detail != "one_of_required" {
		t.Fatalf("errOneOfRequired() detail = %q, want %q", data.Detail, "one_of_required")
	}
	if len(data.Fields) != 2 || data.Fields[0] != "content_base64" || data.Fields[1] != "content_uri" {
		t.Fatalf("errOneOfRequired() fields = %#v, want [content_base64 content_uri]", data.Fields)
	}
	if rpcErr.Message != "content_base64 or content_uri is required" {
		t.Fatalf("errOneOfRequired() message = %q, want %q", rpcErr.Message, "content_base64 or content_uri is required")
	}
}

func TestErrMutuallyExclusiveFieldsReturnsFieldsMetadata(t *testing.T) {
	rpcErr, data := requireRPCError(t, errMutuallyExclusiveFields("content_uri", "content_base64"))
	if data.Detail != "mutually_exclusive" {
		t.Fatalf("errMutuallyExclusiveFields() detail = %q, want %q", data.Detail, "mutually_exclusive")
	}
	if len(data.Fields) != 2 || data.Fields[0] != "content_uri" || data.Fields[1] != "content_base64" {
		t.Fatalf("errMutuallyExclusiveFields() fields = %#v, want [content_uri content_base64]", data.Fields)
	}
	if rpcErr.Message != "provide content_uri or content_base64, not both" {
		t.Fatalf("errMutuallyExclusiveFields() message = %q, want %q", rpcErr.Message, "provide content_uri or content_base64, not both")
	}
}

func TestErrEntityNotFoundReturnsEntityMetadata(t *testing.T) {
	rpcErr, data := requireRPCError(t, errEntityNotFound("thought", "thought_id", "123"))
	if rpcErr.Code != codeEntityNotFound {
		t.Fatalf("errEntityNotFound() code = %d, want %d", rpcErr.Code, codeEntityNotFound)
	}
	if data.Type != mcperrors.TypeEntityNotFound {
		t.Fatalf("errEntityNotFound() type = %q, want %q", data.Type, mcperrors.TypeEntityNotFound)
	}
	if data.Entity != "thought" {
		t.Fatalf("errEntityNotFound() entity = %q, want %q", data.Entity, "thought")
	}
	if data.Field != "thought_id" {
		t.Fatalf("errEntityNotFound() field = %q, want %q", data.Field, "thought_id")
	}
	if data.Value != "123" {
		t.Fatalf("errEntityNotFound() value = %q, want %q", data.Value, "123")
	}
}
