package bootstrapimpl

import (
	"strings"
	"testing"
)

// These tests lock in the security-critical invariant for permission dedup:
// merges must NEVER widen an explicit `false` to `true`. The fix replaced the
// old MAX/GREATEST (most-permissive) merge with MIN/LEAST (least-permissive)
// plus conflict logging. See #1374.

func TestPermLeastPermissiveMergeSQL_UsesMinNotMax(t *testing.T) {
	sql := buildPermLeastPermissiveMergeSQL(
		"ObjectPermissions",
		[]string{"ParentId", "SobjectType"},
		[]string{"PermissionsRead", "PermissionsCreate", "PermissionsEdit"},
	)
	if strings.Contains(sql, "MAX(") {
		t.Fatalf("dedup merge must not widen via MAX; got: %s", sql)
	}
	for _, col := range []string{"PermissionsRead", "PermissionsCreate", "PermissionsEdit"} {
		if !strings.Contains(sql, "MIN(`"+col+"`)") {
			t.Fatalf("expected least-permissive MIN(%s), got: %s", col, sql)
		}
	}
	// Only live rows participate (a soft-deleted tombstone must not drag a live
	// grant to least-permissive, nor be rewritten): aggregate filters IsDeleted=0
	// and the UPDATE only touches live rows.
	if !strings.Contains(sql, "WHERE `IsDeleted` = 0") {
		t.Fatalf("MIN merge must aggregate only live rows (WHERE IsDeleted=0), got: %s", sql)
	}
	if !strings.Contains(sql, "t.`IsDeleted` = 0") {
		t.Fatalf("MIN merge must update only live rows (t.IsDeleted=0), got: %s", sql)
	}
}

func TestPermConflictDetectSQL_FlagsDisagreement(t *testing.T) {
	sql := buildPermConflictDetectSQL(
		"FieldPermissions",
		[]string{"ParentId", "SobjectType", "Field"},
		[]string{"PermissionsRead", "PermissionsEdit"},
	)
	// A conflict = a group where MIN <> MAX for some flag (both true and false present).
	for _, col := range []string{"PermissionsRead", "PermissionsEdit"} {
		if !strings.Contains(sql, "MIN(`"+col+"`) <> MAX(`"+col+"`)") {
			t.Fatalf("expected MIN<>MAX conflict test for %s, got: %s", col, sql)
		}
	}
	if !strings.Contains(sql, "GROUP BY `ParentId`, `SobjectType`, `Field`") {
		t.Fatalf("conflict detection must group by the full unique key, got: %s", sql)
	}
	if !strings.Contains(sql, "WHERE `IsDeleted` = 0") {
		t.Fatalf("conflict detection must consider only live rows (WHERE IsDeleted=0), got: %s", sql)
	}
}
