"""Direct backtest subprocess runner.

Invoked by the web server as a subprocess:
    python -m apps.web.direct_runner TASK_ID CONFIG_PATH CAPITAL START_DATE END_DATE RESULT_FILE [--parking PRESET] [--idle-alpha PRESET] [--form4-sleeve PRESET] [--ownership-sleeve PRESET] [--risk-off-sleeve PRESET] [--non-core-allocator-v2-mode MODE]

Runs run_backtest_session_sync() and saves the result JSON to RESULT_FILE.
Exits 0 on success, non-zero on failure.
"""
from __future__ import annotations

import datetime as dt
import json
import sys
from pathlib import Path


def _json_default(obj):
    if isinstance(obj, (dt.date, dt.datetime)):
        return obj.isoformat()
    raise TypeError(f"Object of type {type(obj)} is not JSON serializable")


def main():
    if len(sys.argv) < 7:
        print(
            "Usage: direct_runner TASK_ID CONFIG_PATH CAPITAL START_DATE END_DATE RESULT_FILE [--parking PRESET] [--idle-alpha PRESET] [--form4-sleeve PRESET] [--ownership-sleeve PRESET] [--risk-off-sleeve PRESET] [--non-core-allocator-v2-mode MODE]",
            file=sys.stderr,
        )
        sys.exit(2)

    task_id   = sys.argv[1]
    config_path = sys.argv[2]
    capital   = float(sys.argv[3])
    start_date = dt.date.fromisoformat(sys.argv[4])
    end_date   = dt.date.fromisoformat(sys.argv[5])
    result_file = Path(sys.argv[6])

    # Optional flags
    parking_preset = None
    idle_alpha_preset = None
    form4_sleeve_preset = None
    ownership_sleeve_preset = None
    risk_off_alpha_sleeve_preset = None
    non_core_allocator_v2_mode = None
    snapshot_id_override = None
    fixed_capital = False
    remaining = sys.argv[7:]
    i = 0
    while i < len(remaining):
        if remaining[i] == "--parking" and i + 1 < len(remaining):
            parking_preset = remaining[i + 1]
            i += 2
        elif remaining[i] == "--idle-alpha" and i + 1 < len(remaining):
            idle_alpha_preset = remaining[i + 1]
            i += 2
        elif remaining[i] == "--form4-sleeve" and i + 1 < len(remaining):
            form4_sleeve_preset = remaining[i + 1]
            i += 2
        elif remaining[i] == "--ownership-sleeve" and i + 1 < len(remaining):
            ownership_sleeve_preset = remaining[i + 1]
            i += 2
        elif remaining[i] == "--risk-off-sleeve" and i + 1 < len(remaining):
            risk_off_alpha_sleeve_preset = remaining[i + 1]
            i += 2
        elif remaining[i] == "--non-core-allocator-v2-mode" and i + 1 < len(remaining):
            non_core_allocator_v2_mode = remaining[i + 1]
            i += 2
        elif remaining[i] == "--snapshot-id" and i + 1 < len(remaining):
            snapshot_id_override = remaining[i + 1]
            i += 2
        elif remaining[i] == "--fixed-capital":
            fixed_capital = True
            i += 1
        else:
            i += 1

    print(f"[direct] {task_id} · {Path(config_path).stem} · {start_date}→{end_date}" +
          (f" · parking={parking_preset}" if parking_preset else "") +
          (f" · idle_alpha={idle_alpha_preset}" if idle_alpha_preset else "") +
          (f" · form4={form4_sleeve_preset}" if form4_sleeve_preset else "") +
          (f" · ownership={ownership_sleeve_preset}" if ownership_sleeve_preset else "") +
          (f" · risk_off={risk_off_alpha_sleeve_preset}" if risk_off_alpha_sleeve_preset else "") +
          (f" · ncav2={non_core_allocator_v2_mode}" if non_core_allocator_v2_mode else "") +
          (f" · snapshot={snapshot_id_override}" if snapshot_id_override else "") +
          (" · fixed_capital" if fixed_capital else ""))
    sys.stdout.flush()

    from apps.paper_trader.backtest_sim import run_backtest_session_sync

    result = run_backtest_session_sync(
        session_name=Path(config_path).stem,
        config_path=config_path,
        initial_equity=capital,
        start_date=start_date,
        end_date=end_date,
        parking_preset=parking_preset,
        idle_alpha_preset=idle_alpha_preset,
        form4_sleeve_preset=form4_sleeve_preset,
        ownership_sleeve_preset=ownership_sleeve_preset,
        risk_off_alpha_sleeve_preset=risk_off_alpha_sleeve_preset,
        non_core_allocator_v2_mode=non_core_allocator_v2_mode,
        snapshot_id_override=snapshot_id_override,
        fixed_capital_sizing=fixed_capital,
    )

    result_file.parent.mkdir(parents=True, exist_ok=True)
    result_file.write_text(json.dumps(result, default=_json_default, indent=2))

    s = result.get("summary", {})
    print(
        f"[direct] done · return={s.get('return_pct', 0):+.2f}% "
        f"trades={s.get('trade_count', 0)} "
        f"sharpe={s.get('sharpe', 0):.2f}"
    )
    sys.stdout.flush()


if __name__ == "__main__":
    main()
