package rest

import (
	"testing"
)

// validateHistoryFilter is the §5.1 Phase-2A predicate gate. The only
// supported predicate is `ParentId = '<literal>'`; any additional clause
// (e.g. `AND Field = 'Description'`, `CreatedDate > ...`) must be
// rejected so the audit surface never silently widens. Error messages
// echo the field name but never the user-supplied value (FLS rule).
func TestValidateHistoryFilter_OnlyParentIdIsAccepted(t *testing.T) {
	cases := []struct {
		name           string
		filter         string
		wantOK         bool
		wantFieldLabel string
	}{
		{"empty filter", "", true, ""},
		{"pure parent id", "ParentId = '001abc'", true, ""},
		{"pure parent id case-insensitive", "parentid = '001abc'", true, ""},
		{"field predicate extra", "ParentId = '001abc' AND Field = 'Description'", false, "Field"},
		{"created date range", "ParentId = '001' AND CreatedDate > 2024-01-01T00:00:00Z", false, "CreatedDate"},
		{"LIKE predicate", "ParentId = '001' AND NewValue LIKE 'foo%'", false, "NewValue"},
		{"no parent id, other predicate", "CreatedById = 'u1'", false, "CreatedById"},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			field, ok := validateHistoryFilter(tc.filter)
			if ok != tc.wantOK {
				t.Fatalf("ok = %v, want %v (filter=%q, field=%q)", ok, tc.wantOK, tc.filter, field)
			}
			if !tc.wantOK && field != tc.wantFieldLabel {
				t.Errorf("field label = %q, want %q", field, tc.wantFieldLabel)
			}
		})
	}
}

// TestValidateHistoryFilter_DoesNotEchoUserValues — the residual check
// must surface a FIELD NAME, never the literal value the user compared
// against. This is the §5.1 FLS error-format invariant.
func TestValidateHistoryFilter_DoesNotEchoUserValues(t *testing.T) {
	secretValue := "leaked-literal-that-must-never-surface"
	filter := "ParentId = '001' AND Secret = '" + secretValue + "'"
	field, ok := validateHistoryFilter(filter)
	if ok {
		t.Fatalf("expected rejection")
	}
	if field == secretValue || field == "'"+secretValue+"'" {
		t.Fatalf("validateHistoryFilter leaked user value: %q", field)
	}
	if field != "Secret" {
		t.Errorf("field label = %q, want %q", field, "Secret")
	}
}
