#!/usr/bin/env python3
# File: src/mcp_servers/noveler/main.py
# Purpose: Thin compatibility wrapper delegating to the presentation-layer MCP
#          server runtime. Keeps legacy import paths stable while the actual
#          implementation resides under noveler.presentation.
"""Legacy entrypoint delegating to the presentation-layer server runtime.

Purpose:
    Provide stable import paths for historical MCP tooling while forwarding
    every call to the presentation-layer runtime module.
Context:
    Used by integration tests and CLI wrappers that still reference
    `mcp_servers.noveler.main` even though the implementation lives under
    `noveler.presentation.mcp.server_runtime`.
Side Effects:
    Mutates `sys.path` to ensure source-root imports resolve correctly.
"""

from __future__ import annotations

import sys
from pathlib import Path
from typing import Any

_SRC_ROOT = Path(__file__).resolve().parents[2]
if str(_SRC_ROOT) not in sys.path:
    sys.path.insert(0, str(_SRC_ROOT))

from noveler.presentation.mcp import server_runtime as _runtime


def _relay(attr: str):
    """Return the named attribute from the presentation-layer runtime module.

    Purpose:
        Reuse shared runtime functions without duplicating implementations.

    Args:
        attr: Name of the attribute to fetch from `_runtime`.

    Returns:
        object | None: Returned runtime attribute, or ``None`` if absent.
    Side Effects:
        None.
    """
    return getattr(_runtime, attr, None)


def _coerce_arguments(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
) -> dict[str, Any]:
    """Merge positional dictionary arguments with keyword overrides.

    Purpose:
        Allow legacy callers to pass a payload either positionally or via
        keyword arguments while always forwarding a dict to the runtime layer.

    Args:
        arguments: Optional dictionary supplied as the first positional arg.
        **kwargs: Additional keyword overrides merged into the payload.

    Returns:
        dict[str, Any]: Combined argument payload.
    Side Effects:
        None.
    """

    merged: dict[str, Any] = {}
    if arguments is not None:
        merged.update(arguments)
    if kwargs:
        merged.update(kwargs)
    return merged

# Progressive Check MCP tools (compliance): get_check_tasks, execute_check_step,
# get_check_status, get_check_history

# Re-export common entrypoints used by CLI / tests.
console = _relay("console")
get_console = _relay("get_console")
server = getattr(_runtime, "server", None)
list_tools = _relay("list_tools")
call_tool = _relay("call_tool")
execute_task_subtask = _relay("execute_task_subtask")
convert_cli_to_json = _relay("convert_cli_to_json")
validate_json_response = _relay("validate_json_response")
wrap_json_text = _relay("wrap_json_text")
apply_path_fallback_from_locals = _relay("apply_path_fallback_from_locals")
resolve_path_service = _relay("resolve_path_service")
execute_novel_command = _relay("execute_novel_command")
execute_status_command = _relay("execute_status_command")


# ---- Explicit delegates (statically discoverable) ----

# Enhanced writing delegates
async def execute_enhanced_get_writing_tasks(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward enhanced writing-task retrieval to the runtime module.

    Purpose:
        Preserve legacy import paths for enhanced writing workflows.

    Args:
        **kwargs: Arbitrary keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result produced by `_runtime.execute_enhanced_get_writing_tasks`.
    Side Effects:
        Depends on the underlying runtime implementation.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_enhanced_get_writing_tasks(payload)

async def execute_enhanced_execute_writing_step(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward enhanced writing-step execution to the runtime module.

    Purpose:
        Maintain backwards compatibility for enhanced writing step delegates.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_enhanced_execute_writing_step`.
    Side Effects:
        Same as the delegated runtime function.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_enhanced_execute_writing_step(payload)

async def execute_enhanced_resume_from_partial_failure(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward partial-failure resume handling to the runtime module.

    Purpose:
        Allow legacy clients to resume enhanced writing flows via this module.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result produced by `_runtime.execute_enhanced_resume_from_partial_failure`.
    Side Effects:
        Follows the behaviour of the runtime delegate.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_enhanced_resume_from_partial_failure(payload)

# Progressive check delegates
async def execute_get_check_tasks(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward progressive-check task retrieval to the runtime module.

    Purpose:
        Keep the progressive check API available under the legacy namespace.

    Args:
        **kwargs: Keyword arguments passed through to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_get_check_tasks`.
    Side Effects:
        Mirrors the delegated implementation.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_get_check_tasks(payload)

async def execute_check_step_command(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward check-step execution to the runtime module.

    Purpose:
        Offer a legacy entrypoint for progressive check step execution.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_check_step_command`.
    Side Effects:
        Determined by the runtime delegate.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_check_step_command(payload)

async def execute_get_check_status(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward progressive-check status retrieval to the runtime module.

    Purpose:
        Maintain compatibility with legacy imports during status checks.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_get_check_status`.
    Side Effects:
        Inherits behaviour from the runtime implementation.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_get_check_status(payload)

async def execute_get_check_history(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward progressive-check history retrieval to the runtime module.

    Purpose:
        Provide a namespaced delegate for inspection of prior check runs.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_get_check_history`.
    Side Effects:
        Mirrors the runtime behaviour.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_get_check_history(payload)

async def execute_generate_episode_preview(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward episode preview generation to the runtime module.

    Purpose:
        Expose preview generation via the legacy MCP module path.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_generate_episode_preview`.
    Side Effects:
        Matches the delegated runtime code.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_generate_episode_preview(payload)

async def execute_run_quality_checks(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward bulk quality checks to the runtime module.

    Purpose:
        Allow callers to trigger quality checks through the legacy facade.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_run_quality_checks`.
    Side Effects:
        Consistent with the runtime delegate.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_run_quality_checks(payload)

async def execute_improve_quality_until(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward iterative quality improvement to the runtime module.

    Purpose:
        Retain backwards compatible access to quality improvement loops.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_improve_quality_until`.
    Side Effects:
        Matches the runtime implementation.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_improve_quality_until(payload)

async def execute_fix_quality_issues(
    arguments: dict[str, Any] | None = None,
    **kwargs: Any,
):  # type: ignore[no-untyped-def]
    """Forward automatic quality issue fixes to the runtime module.

    Purpose:
        Bridge legacy tooling to the presentation-layer fix workflow.

    Args:
        **kwargs: Keyword arguments forwarded to the runtime helper.

    Returns:
        Any: Result from `_runtime.execute_fix_quality_issues`.
    Side Effects:
        Dependent on the delegated implementation.
    """
    payload = _coerce_arguments(arguments, **kwargs)
    return await _runtime.execute_fix_quality_issues(payload)


async def _legacy_list_tools_impl() -> list[dict]:
    """List available MCP tools using the legacy-compatible delegate.

    Purpose:
        Maintain a discoverable symbol for older test harnesses.

    Args:
        None.

    Returns:
        list[dict]: Tool metadata emitted by `_runtime.list_tools`.
    Side Effects:
        None beyond the delegated runtime call.
    """
    return await _runtime.list_tools()


async def main() -> None:
    """Execute the presentation-layer server runtime entrypoint.

    Purpose:
        Provide a legacy-compatible async entrypoint for launching the server.

    Args:
        None.

    Returns:
        None.
    Side Effects:
        Runs the underlying runtime which configures stdio and event loops.
    """

    await _runtime.main()


def __getattr__(name: str):  # pragma: no cover - passthrough helper
    """Defer attribute access to the presentation-layer runtime module.

    Purpose:
        Ensure undefined attributes fall back to the runtime module.

    Args:
        name: Attribute name requested by the caller.

    Returns:
        Any: Attribute fetched from `_runtime`.
    Side Effects:
        None.
    """

    return getattr(_runtime, name)


__all__ = sorted({
    "console",
    "get_console",
    "server",
    "list_tools",
    "call_tool",
    "execute_task_subtask",
    "convert_cli_to_json",
    "validate_json_response",
    "wrap_json_text",
    "apply_path_fallback_from_locals",
    "resolve_path_service",
    "execute_novel_command",
    "execute_status_command",
    # Explicit delegates (discoverable by static tools)
    "execute_enhanced_get_writing_tasks",
    "execute_enhanced_execute_writing_step",
    "execute_enhanced_resume_from_partial_failure",
    "execute_get_check_tasks",
    "execute_check_step_command",
    "execute_get_check_status",
    "execute_get_check_history",
    "execute_generate_episode_preview",
    "execute_run_quality_checks",
    "execute_improve_quality_until",
    "execute_fix_quality_issues",
    "_legacy_list_tools_impl",
    "main",
})


if __name__ == "__main__":
    import asyncio

    asyncio.run(main())
