"""Offline preflight for an unsigned scope manifest; never grants authority."""
from datetime import UTC, datetime
from .models import Effect, ScopeManifest
from .resources import normalize_resource
from .canonical import sha256_value
from .errors import ResourceError


def inspect_manifest(manifest: ScopeManifest, *, at: datetime | None = None) -> dict:
    now = at or datetime.now(UTC)
    if now.tzinfo is None:
        raise ValueError("inspection time must include a timezone")
    findings = []
    rules = []
    def finding(code, severity, message, rule_id=None):
        findings.append(dict(code=code, severity=severity, message=message, rule_id=rule_id))
    if now >= manifest.expires_at:
        finding("expired", "error", "This manifest has expired. Issue a new run identity and time window.")
    if now < manifest.not_before:
        finding("not_yet_active", "warning", "The run cannot begin before its not_before timestamp.")
    if not manifest.pause_on_scope_uncertainty:
        finding("uncertainty_pause_disabled", "warning", "Scope-uncertainty pausing is disabled in this manifest.")
    for rule in manifest.rules:
        normalized = None
        try:
            normalized = normalize_resource(rule.resource, pattern=True).value
        except ResourceError as exc:
            finding("invalid_resource", "error", str(exc), rule.rule_id)
        if rule.effect == Effect.ALLOW:
            if rule.action.endswith(".*"):
                finding("action_family", "warning", "This rule permits an action family. Prefer the exact adapter action when possible.", rule.rule_id)
            if rule.max_uses is None:
                finding("unbounded_rule_uses", "warning", "No per-rule use count is set; expiry and other policy checks still apply.", rule.rule_id)
            if rule.action == "network.http" and not rule.methods:
                finding("unrestricted_methods", "warning", "HTTP methods are unrestricted by this rule.", rule.rule_id)
            if rule.allow_private_network:
                finding("private_network", "warning", "This rule explicitly permits private network destinations.", rule.rule_id)
        rules.append(dict(rule_id=rule.rule_id,effect=rule.effect.value,action=rule.action,resource=normalized,methods=list(rule.methods),max_uses=rule.max_uses))
    return dict(schema_version="1.0", valid=not any(f['severity']=='error' for f in findings), run_id=manifest.run_id, manifest_sha256=sha256_value(manifest.model_dump(mode="json")), inspected_at=now.isoformat(), expires_at=manifest.expires_at.isoformat(), rules=rules, findings=findings, authority_granted=False, boundary="Unsigned static inspection only. Signature, trusted principal, nonce, revocation, live resource resolution, and consume-once checks still run at authorization time.")
