"""
backtest_strategy — run a PandasStrategy against historical OHLC data.

Spawns backtest_harness.py as a subprocess so user strategy code is isolated
from the MCP server process. The harness handles API init, data fetch, and
the synchronous BacktestEngine internally.
"""

import asyncio
import json
import logging
import sys
from pathlib import Path
from typing import Any

log = logging.getLogger(__name__)

_BACKTEST_HARNESS = Path(__file__).parent / "backtest_harness.py"


async def backtest_strategy(
    strategy_name: str,
    feeds: list[dict],
    from_time: Any,
    to_time: Any,
    initial_capital: float = 10_000.0,
    paper: bool = True,
) -> list:
    """
    Load a saved strategy, fetch OHLC+ data for each feed, and run a backtest.

    Args:
        strategy_name: Display name as saved via PythonWrite("strategy", ...)
        feeds: List of feed dicts, e.g. [{"symbol": "BTC/USDT.BINANCE", "period_seconds": 3600}]
        from_time: Backtest start (Unix timestamp or date string)
        to_time:   Backtest end   (Unix timestamp or date string)
        initial_capital: Starting balance in quote currency (default 10,000)
        paper: Always True for historical backtest (flag reserved for forward testing)

    Returns:
        list[TextContent] with JSON payload containing backtest metrics.
        On error: [TextContent] with {"error": str}
    """
    from mcp.types import TextContent

    def _err(msg: str) -> list:
        log.error("backtest_strategy '%s': %s", strategy_name, msg)
        return [TextContent(type="text", text=json.dumps({"error": msg}))]

    if not feeds:
        return _err("feeds list is empty — provide at least one {symbol, period_seconds} entry")

    for f in feeds:
        if not f.get("symbol"):
            return _err(f"Feed entry missing 'symbol': {f}")

    cfg = {
        "strategy_name": strategy_name,
        "feeds": feeds,
        "from_time": from_time,
        "to_time": to_time,
        "initial_capital": initial_capital,
        "paper": paper,
    }

    try:
        proc = await asyncio.create_subprocess_exec(
            sys.executable, str(_BACKTEST_HARNESS),
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE,
        )
        stdout, stderr = await asyncio.wait_for(
            proc.communicate(json.dumps(cfg).encode()),
            timeout=600,
        )
    except asyncio.TimeoutError:
        return _err("Backtest timed out (10 minutes)")
    except Exception as exc:
        return _err(f"Failed to launch backtest harness: {exc}")

    if proc.returncode != 0:
        err_text = stderr.decode(errors="replace")
        log.error("backtest_strategy '%s': harness exited %d: %s", strategy_name, proc.returncode, err_text[:500])
        return _err(f"Backtest harness failed:\n{err_text}")

    if stderr:
        log.warning("backtest_strategy '%s' stderr: %s", strategy_name, stderr.decode(errors="replace")[:500])

    try:
        payload = json.loads(stdout.decode())
    except json.JSONDecodeError:
        return _err(f"Harness produced invalid JSON: {stdout.decode(errors='replace')[:200]}")

    if "error" in payload:
        return _err(payload["error"])

    return [TextContent(type="text", text=json.dumps(payload))]
