package models

import (
	"testing"

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

// TestRowVisibilityForMapping locks the ONE app-blind SharingModel->neutral-policy
// translation (L0-D D1) to the exact current enforcement behavior for all six
// SharingModel tokens plus the default (empty / unknown) case.
func TestRowVisibilityForMapping(t *testing.T) {
	cases := []struct {
		name             string
		model            constants.SharingModel
		wantKind         RowVisibilityKind
		wantFolderScope  string
	}{
		{"PublicRead", constants.SharingModelPublicRead, RowVisibilityPublicRead, ""},
		{"PublicReadWrite", constants.SharingModelPublicReadWrite, RowVisibilityPublicReadWrite, ""},
		{"ControlledByParent", constants.SharingModelControlledByParent, RowVisibilityParentControlled, ""},
		{"FolderSharing", constants.SharingModelFolderSharing, RowVisibilityFolderScoped, ""},
		{"FolderContentSharing", constants.SharingModelFolderContentSharing, RowVisibilityFolderScoped, "FolderId"},
		{"Private", constants.SharingModelPrivate, RowVisibilityPrivate, ""},
		{"empty", constants.SharingModel(""), RowVisibilityPrivate, ""},
		{"unknown", constants.SharingModel("SomethingElse"), RowVisibilityPrivate, ""},
	}

	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			schema := &ObjectMetadata{SharingModel: tc.model}
			got := RowVisibilityFor(schema)
			if got.Kind != tc.wantKind {
				t.Fatalf("Kind = %v, want %v", got.Kind, tc.wantKind)
			}
			if got.FolderScopeField != tc.wantFolderScope {
				t.Fatalf("FolderScopeField = %q, want %q", got.FolderScopeField, tc.wantFolderScope)
			}
		})
	}
}

// TestRowVisibilityForNilSchema locks the defensive nil case: a stray nil never
// widens visibility, it collapses to Private.
func TestRowVisibilityForNilSchema(t *testing.T) {
	got := RowVisibilityFor(nil)
	if got.Kind != RowVisibilityPrivate {
		t.Fatalf("nil schema Kind = %v, want RowVisibilityPrivate", got.Kind)
	}
	if got.FolderScopeField != "" {
		t.Fatalf("nil schema FolderScopeField = %q, want empty", got.FolderScopeField)
	}
	if got.HierarchyGranted {
		t.Fatalf("nil schema HierarchyGranted = true, want false")
	}
}

// TestRowVisibilityForHierarchyGranted confirms HierarchyGranted mirrors
// EnableHierarchySharing on every Kind (byte-identical owner-suffix input).
func TestRowVisibilityForHierarchyGranted(t *testing.T) {
	for _, model := range []constants.SharingModel{
		constants.SharingModelPrivate,
		constants.SharingModelPublicRead,
		constants.SharingModelPublicReadWrite,
		constants.SharingModelControlledByParent,
		constants.SharingModelFolderSharing,
		constants.SharingModelFolderContentSharing,
	} {
		for _, enabled := range []bool{true, false} {
			schema := &ObjectMetadata{SharingModel: model, EnableHierarchySharing: enabled}
			if got := RowVisibilityFor(schema); got.HierarchyGranted != enabled {
				t.Fatalf("model=%s enabled=%v: HierarchyGranted = %v", model, enabled, got.HierarchyGranted)
			}
		}
	}
}
