package zddc

// CascadeMode selects the access-decision algorithm used by AllowedAction.
//
// ModeDelegated (default) preserves the historical commercial-tenant
// behavior: the cascade walks leaf→root and the first level with a
// matching entry decides. Subtree allows can override ancestor denies —
// this is the load-bearing delegation primitive that lets a subtree
// owner grant access without root-admin involvement.
//
// ModeStrict implements the federal posture (NIST AC-6 "least
// privilege"): a deny anywhere in the ancestor chain is absolute and
// cannot be overridden by a leaf grant. Implemented as a two-pass
// evaluation — first walk root→leaf for any matching explicit deny,
// then walk leaf→root for the grant.
//
// The mode is operator-controlled at startup via --cascade-mode (config
// flag) or ZDDC_CASCADE_MODE (env var). Subtree .zddc files cannot
// override the mode — it is a deployment-wide policy.
type CascadeMode int

const (
	ModeDelegated CascadeMode = iota
	ModeStrict
)

// String returns the operator-facing name (matches the flag value).
func (m CascadeMode) String() string {
	switch m {
	case ModeStrict:
		return "strict"
	default:
		return "delegated"
	}
}

// ParseCascadeMode resolves a flag/env string to a CascadeMode. Empty
// or unrecognized input defaults to ModeDelegated; the caller can warn
// on unrecognized values, but the safe default is the existing behavior.
func ParseCascadeMode(s string) (CascadeMode, bool) {
	switch s {
	case "", "delegated":
		return ModeDelegated, true
	case "strict":
		return ModeStrict, true
	}
	return ModeDelegated, false
}
