from __future__ import annotations

import json

import pytest

from src.services.javascript_package_inventory import load_latest_javascript_package_inventory


def test_load_latest_javascript_package_inventory_reads_newest_file(tmp_path):
    older = _snapshot(generated_at="2026-06-03T00:00:00+08:00", completion=93)
    newer = _snapshot(generated_at="2026-06-04T00:00:00+08:00", completion=95)
    (tmp_path / "javascript_package_inventory_2026-06-03.json").write_text(
        json.dumps(older),
        encoding="utf-8",
    )
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(newer),
        encoding="utf-8",
    )

    loaded = load_latest_javascript_package_inventory(tmp_path)

    assert loaded["generated_at"] == "2026-06-04T00:00:00+08:00"
    assert loaded["program_status"]["overall_completion_percent"] == 95
    assert loaded["rollups"]["total_workspaces"] == 2
    assert loaded["operation_boundaries"]["lockfile_write_allowed"] is False


def test_javascript_package_inventory_requires_read_only_mode(tmp_path):
    snapshot = _snapshot()
    snapshot["program_status"]["read_only_mode"] = False
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="read_only_mode"):
        load_latest_javascript_package_inventory(tmp_path)


def test_javascript_package_inventory_requires_blocked_operations(tmp_path):
    snapshot = _snapshot()
    snapshot["operation_boundaries"]["pnpm_install_allowed"] = True
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="operation boundaries"):
        load_latest_javascript_package_inventory(tmp_path)


def test_javascript_package_inventory_requires_lockfile_write_blocked(tmp_path):
    snapshot = _snapshot()
    snapshot["lockfile_summary"]["write_allowed"] = True
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="write_allowed"):
        load_latest_javascript_package_inventory(tmp_path)


def test_javascript_package_inventory_requires_workspace_rollup_consistency(tmp_path):
    snapshot = _snapshot()
    snapshot["rollups"]["action_required_workspace_ids"] = []
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="action_required_workspace_ids"):
        load_latest_javascript_package_inventory(tmp_path)


def test_javascript_package_inventory_requires_dependency_total_consistency(tmp_path):
    snapshot = _snapshot()
    snapshot["rollups"]["total_direct_dependencies"] = 999
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="total_direct_dependencies"):
        load_latest_javascript_package_inventory(tmp_path)


def test_javascript_package_inventory_requires_drift_rollup_consistency(tmp_path):
    snapshot = _snapshot()
    snapshot["lockfile_drift"]["specifier_mismatches"] = [{"name": "next"}]
    (tmp_path / "javascript_package_inventory_2026-06-04.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="manifest_lock_mismatch_count"):
        load_latest_javascript_package_inventory(tmp_path)


def test_javascript_package_inventory_fails_when_missing(tmp_path):
    with pytest.raises(FileNotFoundError):
        load_latest_javascript_package_inventory(tmp_path)


def _snapshot(
    *,
    generated_at: str = "2026-06-04T00:00:00+08:00",
    completion: int = 95,
) -> dict:
    return {
        "schema_version": "javascript_package_inventory_v1",
        "generated_at": generated_at,
        "program_status": {
            "overall_completion_percent": completion,
            "current_priority": "P1",
            "current_task_id": "P1-202",
            "next_task_id": "P1-203",
            "read_only_mode": True,
        },
        "source_refs": ["package.json", "pnpm-lock.yaml"],
        "lockfile_summary": {
            "lockfile_ref": "pnpm-lock.yaml",
            "lockfile_version": "9.0",
            "importer_count": 2,
            "package_entry_count": 10,
            "snapshot_entry_count": 10,
            "settings": {"autoInstallPeers": True},
            "status": "in_sync",
            "write_allowed": False,
        },
        "rollups": {
            "total_workspaces": 2,
            "total_direct_dependencies": 3,
            "production_dependency_count": 2,
            "dev_dependency_count": 1,
            "workspace_dependency_count": 1,
            "external_dependency_count": 2,
            "caret_specifier_count": 2,
            "exact_specifier_count": 0,
            "tilde_specifier_count": 0,
            "manifest_lock_mismatch_count": 0,
            "missing_in_lockfile_count": 0,
            "extra_in_lockfile_count": 0,
            "by_status": {"ready": 1, "action_required": 1},
            "action_required_workspace_ids": ["apps_web"],
            "planned_next_workspace_ids": [],
        },
        "workspaces": [
            _workspace("root_workspace", "ready", 1),
            _workspace("apps_web", "action_required", 2),
        ],
        "lockfile_drift": {
            "status": "in_sync",
            "missing_in_lockfile": [],
            "specifier_mismatches": [],
            "extra_in_lockfile": [],
        },
        "drift_findings": [
            {
                "finding_id": "manifest_lockfile_in_sync",
                "severity": "low",
                "status": "accepted",
                "summary": "in sync",
                "evidence_refs": ["pnpm-lock.yaml"],
                "next_action": "watch",
            }
        ],
        "operation_boundaries": {
            "read_only_api_allowed": True,
            "package_installation_allowed": False,
            "package_upgrade_allowed": False,
            "lockfile_write_allowed": False,
            "external_cve_lookup_allowed": False,
            "npm_audit_allowed": False,
            "pnpm_install_allowed": False,
            "production_routing_allowed": False,
        },
        "approval_boundaries": {
            "sdk_installation_allowed": False,
            "paid_api_call_allowed": False,
            "shadow_or_canary_allowed": False,
            "production_routing_allowed": False,
            "destructive_operation_allowed": False,
        },
    }


def _workspace(workspace_id: str, status: str, total_dependencies: int) -> dict:
    return {
        "workspace_id": workspace_id,
        "display_name": workspace_id,
        "manifest_ref": "package.json",
        "lockfile_importer": ".",
        "status": status,
        "risk_level": "high" if status == "action_required" else "medium",
        "private_package": True,
        "package_manager": "pnpm@9.0.0",
        "dependency_counts": {
            "dependencies": total_dependencies,
            "devDependencies": 0,
            "peerDependencies": 0,
            "optionalDependencies": 0,
            "total": total_dependencies,
        },
        "specifier_counts": {
            "workspace": 0,
            "caret": total_dependencies,
            "exact": 0,
            "tilde": 0,
            "other": 0,
        },
        "workspace_dependency_names": [],
        "evidence_refs": ["package.json"],
        "next_action": "next",
    }
