package contract

import (
	"errors"
	"strings"
	"testing"
)

func TestHistoryQueryErrorKindsAreNeutralAndClassifiable(t *testing.T) {
	kinds := []HistoryQueryErrorKind{
		HistoryQueryErrorObjectPermissionDenied,
		HistoryQueryErrorRecordVisibilityDenied,
		HistoryQueryErrorMalformed,
		HistoryQueryErrorUnavailable,
		HistoryQueryErrorInternal,
	}
	for _, kind := range kinds {
		t.Run(string(kind), func(t *testing.T) {
			err := &HistoryQueryError{Kind: kind}
			if got := err.Error(); got != string(kind) {
				t.Fatalf("kind fallback Error() = %q, want %q", got, kind)
			}
			assertNoAppVocabulary(t, string(kind), err.Error())
		})
	}

	cause := errors.New("inventory history store offline")
	err := &HistoryQueryError{
		Kind:  HistoryQueryErrorUnavailable,
		Cause: cause,
	}
	if got := err.Error(); got != cause.Error() {
		t.Fatalf("cause fallback Error() = %q, want %q", got, cause.Error())
	}
	if !errors.Is(err, cause) {
		t.Fatal("HistoryQueryError should unwrap its cause")
	}

	err.Message = "history service unavailable for work item"
	if got := err.Error(); got != err.Message {
		t.Fatalf("message Error() = %q, want %q", got, err.Message)
	}
	assertNoAppVocabulary(t, err.Error())
}

func TestFieldDeniedByFLSErrorIsSeparateNeutralPlannerError(t *testing.T) {
	err := &FieldDeniedByFLSError{FieldApiName: "SensitiveNote"}
	var denied *FieldDeniedByFLSError
	if !errors.As(err, &denied) {
		t.Fatal("FieldDeniedByFLSError should classify by concrete type")
	}
	if got := err.HTTPStatus(); got != 400 {
		t.Fatalf("HTTPStatus = %d, want 400", got)
	}
	assertNoAppVocabulary(t, err.Error())
}

func assertNoAppVocabulary(t *testing.T, values ...string) {
	t.Helper()
	for _, value := range values {
		lower := strings.ToLower(value)
		for _, forbidden := range []string{"salesforce", "c" + "rm", "account", "soql", "v63"} {
			if strings.Contains(lower, forbidden) {
				t.Fatalf("shared contract surface %q contains forbidden application vocabulary %q", value, forbidden)
			}
		}
	}
}
