"""Project usage rows from stored execution-identity refs."""
from __future__ import annotations

import json
from pathlib import Path
from collections.abc import Mapping
from typing import Any

from .execution_identity import (
    ExecutionManifest,
    execution_identity_for_ref,
    stored_execution_label,
    stored_identity,
)
from .execution_manifest import read_execution_manifest
from .json_boundary import load_owned_object


def run_execution_manifest(run_root: Path) -> ExecutionManifest:
    """Load the first run-manifest under ``run_root/manifests``."""
    return read_execution_manifest(_manifest_path(run_root))


def identity_rows_from_state(state: Mapping[str, Any] | None) -> list[dict[str, Any]]:
    """Collect stored identity rows from a team-state document."""
    if not isinstance(state, Mapping):
        return []
    rows: list[dict[str, Any]] = []
    seen: set[str] = set()
    for collection in (
        state.get("workers") or [],
        state.get("workerDispatches") or [],
        state.get("agentDispatches") or [],
    ):
        if not isinstance(collection, list):
            continue
        for item in collection:
            ident = stored_identity(item if isinstance(item, Mapping) else None)
            if not ident:
                continue
            key = str(ident.get("roleExecutionRef") or ident.get("executionLabel"))
            if key in seen:
                continue
            seen.add(key)
            rows.append(ident)
    return rows


def collect_usage_rows(run_root: Path) -> list[dict[str, Any]]:
    """Project usage rows with stored execution identity refs."""
    manifest = run_execution_manifest(run_root)
    team_state = _load_json(run_root / "state" / "team-state.json")
    rows: list[dict[str, Any]] = []
    for collection in (
        team_state.get("workerDispatches") or [],
        team_state.get("agentDispatches") or [],
    ):
        for item in collection:
            if not isinstance(item, Mapping):
                continue
            rows.append(_usage_row(manifest, item))
    return rows


def _usage_row(manifest: ExecutionManifest, item: Mapping[str, Any]) -> dict[str, Any]:
    ref = str(item.get("roleExecutionRef") or "")
    role = execution_identity_for_ref(manifest, ref)
    return {
        "participantRef": item.get("participantRef") or role.participant_ref,
        "roleExecutionRef": role.role_execution_ref,
        "invocationRef": item.get("invocationRef"),
        "attempt": item.get("attempt", 1),
        "executionLabel": stored_execution_label(
            {"executionLabel": item.get("executionLabel") or role.execution_label}
        ),
    }


def _manifest_path(run_root: Path) -> Path:
    manifests = run_root / "manifests"
    for path in sorted(manifests.glob("*.json")):
        return path
    raise FileNotFoundError(f"no run manifest under {run_root}")


def _load_json(path: Path) -> dict[str, Any]:
    return load_owned_object(path, artifact="usage identity source")
