package layoutroutingsecurityv1

const (
	// ViewCanonicalizationVersion is both the supported v1 canonical grammar
	// and its digest-domain separator.
	ViewCanonicalizationVersion = "nexuscrm.layout-routing-security-view-canonical/v1"
	// KeyGrammarVersion versions the canonical ProfileKey and RoleKey grammar.
	KeyGrammarVersion = "nexuscrm.layout-routing-security-key/v1"
	// RoleTopologyGrammarVersion versions the direct-parent forest grammar. It
	// is not an org state counter or selector.
	RoleTopologyGrammarVersion = "nexuscrm.layout-routing-role-topology/v1"

	// MaxOrgIDBytes is the portable cross-repository bound for the canonical
	// UTF-8 org identity, independent of any database column or collation.
	MaxOrgIDBytes = 255
	// MaxNamespaceIDBytes and MaxLocalKeyBytes bound canonical stable keys.
	MaxNamespaceIDBytes = 128
	MaxLocalKeyBytes    = 128
	// MaxKeySegmentBytes bounds each lowercase ASCII dot-separated segment.
	MaxKeySegmentBytes = 63
	// MaxResolvedIDBytes bounds an opaque target-local Profile or Role ID.
	MaxResolvedIDBytes = 255
	// MaxProfileIdentities and MaxRoleIdentities bound one complete org view.
	MaxProfileIdentities = 100_000
	MaxRoleIdentities    = 100_000
	// MaxCanonicalViewBytes bounds the v1 canonical content artifact.
	MaxCanonicalViewBytes = 64 << 20
)

// IdentityState describes whether a reserved typed-key/local-ID pair resolves
// to a current non-deleted row. Operational Profile activity is not identity
// deletion and is intentionally absent from this state.
type IdentityState string

const (
	IdentityStateActive    IdentityState = "ACTIVE"
	IdentityStateTombstone IdentityState = "TOMBSTONE"
)

// ProfileKey is the immutable portable identity of one Profile. It remains a
// distinct Go type from RoleKey even though both use the same field grammar.
type ProfileKey struct {
	NamespaceID string
	LocalKey    string
}

// RoleKey is the immutable portable identity of one Role.
type RoleKey struct {
	NamespaceID string
	LocalKey    string
}

// ProfileIdentity records one permanently reserved Profile key/local-ID pair.
// A tombstone retains ResolvedProfileID for non-reuse checks but cannot resolve
// a layout assignment.
type ProfileIdentity struct {
	Key               ProfileKey
	ResolvedProfileID string
	State             IdentityState
}

// RoleIdentity records one permanently reserved Role key/local-ID pair and,
// for an active Role, its optional direct parent. Tombstones cannot have a
// parent.
type RoleIdentity struct {
	Key            RoleKey
	ResolvedRoleID string
	State          IdentityState
	ParentRoleKey  *RoleKey
}

// View is the complete org Profile/Role identity ledger projection and active
// direct-parent Role forest. Collections must be present; their input order is
// not semantic because CanonicalizeView sorts by typed key.
type View struct {
	OrgID                      string
	CanonicalizationVersion    string
	KeyGrammarVersion          string
	RoleTopologyGrammarVersion string
	Profiles                   []ProfileIdentity
	Roles                      []RoleIdentity
}

// Binding identifies the independently attested layout-routing security view
// for one org at one exact SecurityEpoch. It is a reference value, not a
// selector and not an independently mutable release entity.
type Binding struct {
	OrgID                           string
	SecurityEpoch                   uint64
	LayoutRoutingSecurityViewDigest string
}
