"""MCP issue tools — create and query the per-job issue register."""

from __future__ import annotations

import logging

from fastmcp.exceptions import ToolError
from fastmcp.tools import tool

from mcp_vm_blackbox.coordination_db import get_db
from mcp_vm_blackbox.models import ResolutionType

_LOG = logging.getLogger(__name__)


@tool
async def vm_issue_create(
    job_id: str,
    vm_name: str,
    classification: str,
    severity: str,
    summary: str,
    detail: str | None = None,
    resolution: str | None = None,
    resolution_type: str | None = None,
    evidence_paths: list[str] | None = None,
    step_id: int | None = None,
) -> dict:
    """Create a structured issue entry in the per-job issue register.

    Called by the inspector when it identifies a problem in the step log
    or on the VM screen. Returns an issue_id for reference in reports.

    Args:
        job_id: Active job identifier.
        vm_name: Target VM name.
        classification: Issue classification — one of: "user-facing",
            "harness", "environment".
        severity: Issue severity — one of: "blocker", "major", "minor",
            "observation".
        summary: One-line summary of the issue.
        detail: Detailed description of the issue. Optional.
        resolution: What was done to resolve the issue. Optional —
            typically null at creation time.
        resolution_type: Resolution category (e.g. "fixed", "workaround",
            "deferred"). Optional — typically null at creation time.
        evidence_paths: List of paths to evidence files (screenshots,
            terminal logs, etc.). Optional.
        step_id: Originating step_id from the job_steps table. Optional —
            omit when the issue spans multiple steps.

    Returns:
        Dict with ``issue_id`` (UUID string), ``created_at`` (ISO-8601),
        ``job_id``, and ``vm_name``.

    Raises:
        ToolError: If job_id does not exist for vm_name, or on DB failure.
    """
    validated_resolution_type: ResolutionType | None = None
    if resolution_type is not None:
        try:
            validated_resolution_type = ResolutionType(resolution_type)
        except ValueError:
            valid = ", ".join(f"{v!r}" for v in ResolutionType)
            raise ToolError(f"Invalid resolution_type {resolution_type!r}. Valid values: {valid}") from None
    db = await get_db()
    try:
        issue_id, created_at = await db.insert_issue(
            job_id=job_id,
            vm_name=vm_name,
            classification=classification,
            severity=severity,
            summary=summary,
            detail=detail,
            resolution=resolution,
            resolution_type=validated_resolution_type,
            evidence_paths=evidence_paths,
            step_id=step_id,
        )
    except ValueError as exc:
        raise ToolError(f"Job {job_id!r} not found on VM {vm_name!r}") from exc
    except Exception as exc:
        raise ToolError(f"Failed to create issue for job {job_id!r}: {exc}") from exc
    return {"issue_id": issue_id, "created_at": created_at, "job_id": job_id, "vm_name": vm_name}


@tool
async def vm_issue_list(
    job_id: str, vm_name: str, classification: str | None = None, severity: str | None = None
) -> dict:
    """List issues in the per-job issue register with optional filters.

    Returns all issues for the specified job, optionally filtered by
    classification and/or severity. Use this to assess job health,
    count blockers, or focus analysis on specific issue categories.

    Args:
        job_id: Job identifier.
        vm_name: Target VM name.
        classification: Filter by classification — one of: "user-facing",
            "harness", "environment". Optional — omit for all.
        severity: Filter by severity — one of: "blocker", "major",
            "minor", "observation". Optional — omit for all.

    Returns:
        Dict with ``issues`` (list of issue dicts) and ``count`` (int).

    Raises:
        ToolError: On unexpected database failure.
    """
    db = await get_db()
    try:
        issues = await db.list_issues(job_id=job_id, vm_name=vm_name, classification=classification, severity=severity)
    except Exception as exc:
        raise ToolError(f"Failed to list issues for job {job_id!r}: {exc}") from exc
    return {"issues": issues, "count": len(issues)}
