package zddc

// WORM (write-once-read-many) zones are declared in the cascade via
// the `worm:` key on a ZddcFile (see file.go). This file resolves the
// effective WORM grant for a principal walking a policy chain.
//
// Replaces the hardcoded IsWormPath / WormFolderLevelIndex / WormMask
// machinery (which keyed off the literal folder names "received" and
// "issued"). The convention now lives in internal/zddc/defaults/ — those
// two folders carry `worm: {}` — and any operator can mark another
// directory WORM by adding `worm:` to its .zddc.

// WormZoneGrant inspects the policy chain for email. If any level in
// the chain (including paths-derived contributions) declares a `worm:`
// map, the path is inside a WORM zone: inWorm is true and grant is the
// UNION of the principal's verb grants across every Worm map in the
// chain, masked to {r, c}. When no level declares worm:, inWorm is
// false and grant is meaningless (returned as 0).
//
// Caller (the policy evaluator) combines this with the normal cascade
// read grant:
//
//	if g, inWorm := WormZoneGrant(chain, email, mode); inWorm {
//	    effective = (normalCascadeVerbs(chain, email, mode) & VerbR) |
//	                (g & VerbsRC)
//	    return effective.Has(requestedVerb)
//	}
//
// i.e. inside a WORM zone, w/d/a are always stripped; c survives only
// via the worm: grant; r survives via the normal ACL or the worm:
// grant. Admins are excluded upstream (handler's IsAdmin bypass).
func WormZoneGrant(chain PolicyChain, email string) (grant VerbSet, inWorm bool) {
	for i := 0; i < len(chain.Levels); i++ {
		wl := chain.Levels[i].Worm
		if wl == nil {
			continue
		}
		inWorm = true
		for _, principal := range wl {
			if MatchesPrincipal(principal, email, chain, i) {
				grant |= VerbsRC // listed controllers get read + write-once-create
			}
		}
	}
	// The embedded baseline could in principle carry a top-level
	// worm: too (it doesn't today — it's declared via paths:), so
	// fold it in for completeness.
	if chain.Embedded.Worm != nil {
		inWorm = true
		for _, principal := range chain.Embedded.Worm {
			if MatchesPattern(principal, email) {
				grant |= VerbsRC
			}
		}
	}
	if !inWorm {
		return 0, false
	}
	return grant, true
}
