"""JSON output helpers for SDD CLI.

This module provides the sole output mechanism for the CLI.
The CLI is JSON-first and currently emits JSON envelopes only.

Design rationale:
- Primary consumers are AI coding assistants (Claude, Cursor, etc.)
- AI agents parse structured data best - no regex/pattern matching needed
- Consistent output format = reliable integration
- Humans can pipe through `jq` if needed

This module wraps the canonical response helpers from foundry_mcp.core.responses
to ensure CLI output matches the response-v2 schema used by MCP tools.
"""

import json
import sys
from dataclasses import asdict
from typing import Any, Mapping, Sequence, NoReturn

from foundry_mcp.cli.logging import generate_request_id, get_request_id, set_request_id
from foundry_mcp.core.responses import error_response, success_response


def _ensure_request_id() -> str:
    request_id = get_request_id()
    if request_id:
        return request_id
    request_id = generate_request_id()
    set_request_id(request_id)
    return request_id


def emit(data: Any) -> None:
    """Emit JSON to stdout.

    This is the single output function for all CLI commands.
    Data is serialized in minified format for smaller payloads.

    Args:
        data: Any JSON-serializable data structure.
    """
    print(json.dumps(data, separators=(",", ":"), default=str))


def emit_error(
    message: str,
    code: str = "INTERNAL_ERROR",
    *,
    error_type: str = "internal",
    remediation: str | None = None,
    details: Mapping[str, Any] | None = None,
) -> NoReturn:
    """Emit error JSON to stderr and exit with code 1.

    Uses foundry_mcp.core.responses.error_response to ensure response-v2 compliance.
    Error info is structured in the `data` field with `error_code`, `error_type`,
    and `remediation` fields. The `error` field contains the human-readable message.

    Args:
        message: Human-readable error description.
        code: Error code in SCREAMING_SNAKE_CASE (e.g., VALIDATION_ERROR, NOT_FOUND).
        error_type: Error category for routing (validation, not_found, internal, etc.).
        remediation: Actionable guidance for resolving the error.
        details: Optional additional error context.

    Raises:
        SystemExit: Always exits with code 1.
    """
    response = error_response(
        message=message,
        error_code=code,
        error_type=error_type,
        remediation=remediation,
        details=details,
        request_id=_ensure_request_id(),
    )
    print(json.dumps(asdict(response), separators=(",", ":"), default=str), file=sys.stderr)
    sys.exit(1)


def emit_success(
    data: Any,
    *,
    warnings: Sequence[str] | None = None,
    pagination: Mapping[str, Any] | None = None,
    telemetry: Mapping[str, Any] | None = None,
    meta: Mapping[str, Any] | None = None,
) -> None:
    """Emit success response envelope to stdout.

    Uses foundry_mcp.core.responses.success_response to ensure response-v2 compliance.
    All responses include meta.version: "response-v2".

    Args:
        data: The operation-specific payload.
        warnings: Non-fatal issues to surface in meta.warnings.
        pagination: Cursor metadata for list results.
        telemetry: Timing/performance metadata.
        meta: Additional metadata to merge into meta object.
    """
    # Handle both dict and non-dict data
    if isinstance(data, dict):
        response = success_response(
            data=data,
            warnings=warnings,
            pagination=pagination,
            telemetry=telemetry,
            meta=meta,
            request_id=_ensure_request_id(),
        )
    else:
        # Wrap non-dict data in a result key
        response = success_response(
            data={"result": data},
            warnings=warnings,
            pagination=pagination,
            telemetry=telemetry,
            meta=meta,
            request_id=_ensure_request_id(),
        )
    emit(asdict(response))
