package permissions

import (
	"testing"

	"github.com/nexuscrm/shared/pkg/constants"
	"github.com/nexuscrm/shared/pkg/models"
)

func TestShouldMaterializeFieldPermissionRowUsesPersistedCapabilities(t *testing.T) {
	tests := []struct {
		name  string
		field *models.FieldMetadata
		want  bool
	}{
		{
			name:  "editable field materializes",
			field: &models.FieldMetadata{APIName: "Email", Createable: true, Updateable: true},
			want:  true,
		},
		{
			name:  "read only field still materializes",
			field: &models.FieldMetadata{APIName: "Name", Createable: false, Updateable: false},
			want:  true,
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			if got := ShouldMaterializeFieldPermissionRow(tc.field); got != tc.want {
				t.Fatalf("ShouldMaterializeFieldPermissionRow(%s) = %v; want %v", tc.field.APIName, got, tc.want)
			}
		})
	}
}

// TestBuildPermissionsForProfileAndSchemaSkipsObjectRowForParentControlled
// pins the seeder OP/FP scope split: when `isParentControlled=true`, the
// builder emits ZERO ObjectPermissions rows (the runtime delegates CRUD to
// the parent) but still emits FieldPermissions rows (FLS is independent per
// child field — AC3).
func TestBuildPermissionsForProfileAndSchemaSkipsObjectRowForParentControlled(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: "OpportunityLineItem",
		Fields: []models.FieldMetadata{
			{APIName: "Email", Createable: true, Updateable: true},
			{APIName: "Name", Createable: false, Updateable: false},
		},
	}

	objPerms, fieldPerms := BuildPermissionsForProfileAndSchema(constants.ProfileStandardUser, "ps-standard", schema, true)
	if len(objPerms) != 0 {
		t.Fatalf("isParentControlled=true must emit 0 OP rows; got %d", len(objPerms))
	}
	if len(fieldPerms) != 2 {
		t.Fatalf("isParentControlled=true must keep FP rows; got %d (want 2)", len(fieldPerms))
	}
	want := map[string]bool{"Email": true, "Name": true}
	for _, fp := range fieldPerms {
		delete(want, fp.Field)
	}
	if len(want) != 0 {
		t.Fatalf("missing field perms for %v", want)
	}
}

func TestBuildPermissionsForProfileAndSchemaIncludesReadOnlyFields(t *testing.T) {
	schema := &models.ObjectMetadata{
		APIName: "User",
		Fields: []models.FieldMetadata{
			{APIName: "Email", Type: constants.FieldTypeEmail, Createable: true, Updateable: true},
			{APIName: "Name", Type: constants.FieldTypeString, Createable: false, Updateable: false},
			{APIName: "LastLoginDate", Type: constants.FieldTypeDatetime, Createable: false, Updateable: false},
		},
	}

	_, fieldPerms := BuildPermissionsForProfileAndSchema(constants.ProfileStandardUser, "ps-standard", schema, false)
	if len(fieldPerms) != 3 {
		t.Fatalf("fieldPerms len = %d; want 3", len(fieldPerms))
	}
	want := map[string]bool{"Email": true, "Name": true, "LastLoginDate": true}
	for _, fp := range fieldPerms {
		delete(want, fp.Field)
	}
	if len(want) != 0 {
		t.Fatalf("missing field perms for %v", want)
	}
}
