from __future__ import annotations

from datetime import UTC, datetime

import pytest

from scopewrit.errors import ManifestError
from scopewrit.manifest_io import load_manifest_yaml_bytes


def _valid_yaml() -> bytes:
    return b"""
schema_version: "1.0"
mandate_id: mandate-yaml-test
run_id: run-yaml-test
principal: yaml-principal
agent_id: yaml-agent
objective: Read exactly one approved status endpoint for the YAML test.
issued_at: 2026-07-30T18:00:00Z
not_before: 2026-07-30T18:00:00Z
expires_at: 2026-07-30T18:10:00Z
nonce: abcdefghijklmnop
rules:
  - rule_id: allow-status
    effect: allow
    action: network.http
    resource: https://example.com/status
    methods: [GET]
pause_on_scope_uncertainty: true
ticket_ttl_seconds: 30
claim_boundary: This YAML fixture only authorizes one explicit HTTP status read.
"""


def test_strict_yaml_loads_one_manifest() -> None:
    manifest = load_manifest_yaml_bytes(_valid_yaml())
    assert manifest.run_id == "run-yaml-test"
    assert manifest.issued_at == datetime(2026, 7, 30, 18, 0, tzinfo=UTC)


def test_duplicate_yaml_keys_are_rejected() -> None:
    body = _valid_yaml().replace(
        b"agent_id: yaml-agent",
        b"agent_id: yaml-agent\nagent_id: substituted-agent",
    )
    with pytest.raises(ManifestError, match="duplicate YAML key"):
        load_manifest_yaml_bytes(body)


def test_multiple_yaml_documents_are_rejected() -> None:
    with pytest.raises(ManifestError, match="exactly one"):
        load_manifest_yaml_bytes(_valid_yaml() + b"\n---\n{}\n")


def test_manifest_size_is_bounded() -> None:
    with pytest.raises(ManifestError, match="256 KiB"):
        load_manifest_yaml_bytes(b"x" * (256 * 1024 + 1))
