"""
GAS_THIN_ADAPTER_POLICY_V1 — Phase 2: Extract
spec/39_gas_thin_adapter_policy.yaml의 extract 단계.

audit_gas_thin_adapter_v1.py 결과(forbidden 23개)를 읽어
각 GAS 함수의 Python canonical 대응을 매핑한다.
결과를 Temp/gas_python_migration_map_v1.json에 저장.
"""
from __future__ import annotations
import json
import sys
from datetime import datetime
from pathlib import Path

ROOT = Path(__file__).parent.parent

# ── GAS forbidden 함수 → Python canonical 매핑 ────────────────────────────
# status:
#   MAPPED      — Python에 동등 구현 존재, GAS 버전 제거 가능
#   NEEDS_STUB  — Python 등가 미존재, stub 신규 작성 필요
#   PARTIAL     — 부분 구현 존재, 확장 필요
MIGRATION_MAP: list[dict] = [
    {
        "gas_file": "gdc_01_fetch_fundamentals.gs",
        "gas_function": "_mergePositionRecord_",
        "responsibility": ["stop_loss"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/convert_xlsx_to_json.py",
        "python_function": "normalize_backdata_harness_payload",
        "note": "포지션 레코드 병합은 convert_xlsx_to_json의 backdata 정규화 로직이 담당",
    },
    {
        "gas_file": "gdc_02_account_satellite.gs",
        "gas_function": "_addTickerRoute_",
        "responsibility": ["unknown"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "calc_semiconductor_cluster",
        "note": "ticker 라우팅 집계는 inject_computed_harness의 cluster/route 집계 로직이 담당",
    },
    {
        "gas_file": "gdf_01_price_metrics.gs",
        "gas_function": "calcApexTradePlan_",
        "responsibility": ["sizing", "normalize"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "compute_position_size",
        "note": "포지션 사이징 계획은 compute_position_size (POSITION_SIZE_V1) 담당",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "assembleHarnessCoreLayers_",
        "responsibility": ["sizing"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "main",
        "note": "하네스 코어 레이어 조립은 inject_computed_harness.main() 전체 파이프라인이 담당",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "applyApexCashPreservationSuite_",
        "responsibility": ["unknown"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "cash_recovery",
        "note": "현금 보존 스위트는 cash_recovery + compute_cash_recovery_optimizer 담당",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "applyApexFeedbackSignalSuite_",
        "responsibility": ["decision"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "compute_final_decision",
        "note": "피드백 신호 스위트는 compute_final_decision + compute_timing_decision 담당",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "applyProposal54BuyBlockLocks_",
        "responsibility": ["decision"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "main",
        "note": "Proposal-54 매수 차단 잠금은 inject_computed_harness의 buy_permission 로직이 담당",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "calcStopBreachAlert_",
        "responsibility": ["stop_loss"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "calc_stop_breach_alerts",
        "note": "직접 대응: calc_stop_breach_alerts (STOP_BREACH_ALERT_V1)",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "calcAbsoluteRiskStopV1_",
        "responsibility": ["stop_loss"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "compute_stop_price_core",
        "note": "절대 리스크 스탑은 compute_stop_price_core (STOP_PRICE_CORE_V1) 담당",
    },
    {
        "gas_file": "gdf_02_harness_assembly.gs",
        "gas_function": "calcTpTriggerAlert_",
        "responsibility": ["take_profit"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "compute_tp_validity",
        "note": "TP 트리거 알람은 compute_tp_validity (TP_TRIGGER_ALERT_V1) 담당",
    },
    {
        "gas_file": "gdf_03_portfolio_gates.gs",
        "gas_function": "calcTpQuantityLadder_",
        "responsibility": ["sizing", "take_profit"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "compute_position_size",
        "note": "TP 수량 사다리는 compute_position_size + TP 비율 적용으로 담당",
    },
    {
        "gas_file": "gdf_03_portfolio_gates.gs",
        "gas_function": "scoreSellCandidate_",
        "responsibility": ["unknown"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "check_sanity",
        "note": "매도 후보 채점은 check_sanity (SELL_PRICE_SANITY_V1) + cash_recovery 순위 담당",
    },
    {
        "gas_file": "gdf_03_portfolio_gates.gs",
        "gas_function": "calcPrices_",
        "responsibility": ["stop_loss", "take_profit"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "compute_stop_price_core",
        "note": "지정가/스탑/TP 가격 계산은 compute_stop_price_core + compute_tp_validity 담당",
    },
    {
        "gas_file": "gdf_03_portfolio_gates.gs",
        "gas_function": "runRouteFlow_",
        "responsibility": ["stop_loss"],
        "status": "NEEDS_STUB",
        "python_module": "tools/gas_thin_adapter_stubs_v1.py",
        "python_function": "stub_run_route_flow",
        "note": "라우트 플로우 실행 — Python harness에 직접 대응 없음. stub 생성 필요.",
    },
    {
        "gas_file": "gdf_03_portfolio_gates.gs",
        "gas_function": "buildOrderBlueprint_",
        "responsibility": ["stop_loss", "take_profit"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "main (order_blueprint_json 조립)",
        "note": "주문 청사진 조립은 compute_formula_outputs 의 blueprint_rows 생성 로직이 담당",
    },
    {
        "gas_file": "gdf_03_portfolio_gates.gs",
        "gas_function": "calcDistributionRiskRow_",
        "responsibility": ["risk_score"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "calc_distribution_detector_per_ticker",
        "note": "설거지 위험 점수는 calc_distribution_detector_per_ticker (DISTRIBUTION_SELL_DETECTOR_V1) 담당",
    },
    {
        "gas_file": "gdf_04_execution_quality.gs",
        "gas_function": "calcProfitPreservationRow_",
        "responsibility": ["stop_loss"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "trailing_stop_v2",
        "note": "이익 보존 래칫은 trailing_stop_v2 (PROFIT_RATCHET_TIERED_V2) 담당",
    },
    {
        "gas_file": "gdf_04_execution_quality.gs",
        "gas_function": "calcSmartCashRaiseV2_",
        "responsibility": ["stop_loss"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "cash_recovery",
        "note": "스마트 현금 조달은 cash_recovery + K2 rebound logic 담당",
    },
    {
        "gas_file": "gdf_04_execution_quality.gs",
        "gas_function": "calcApexExecutionHarness_",
        "responsibility": ["sizing", "normalize", "decision"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "main",
        "note": "Apex 실행 하네스 전체는 inject_computed_harness.main() 파이프라인이 담당",
    },
    {
        "gas_file": "gdf_04_execution_quality.gs",
        "gas_function": "calcCashPreservationSellEngineV2_",
        "responsibility": ["sizing"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/inject_computed_harness.py",
        "python_function": "cash_recovery",
        "note": "현금 보존 매도 엔진은 cash_recovery (CASH_RECOVERY_OPTIMIZER_V1) 담당",
    },
    {
        "gas_file": "gdf_04_execution_quality.gs",
        "gas_function": "calcExportGate_",
        "responsibility": ["unknown"],
        "status": "NEEDS_STUB",
        "python_module": "tools/gas_thin_adapter_stubs_v1.py",
        "python_function": "stub_calc_export_gate",
        "note": "export gate 계산 — Python harness에 직접 대응 없음. stub 생성 필요.",
    },
    {
        "gas_file": "gdf_04_execution_quality.gs",
        "gas_function": "buildWatchLedger_",
        "responsibility": ["stop_loss", "take_profit"],
        "status": "NEEDS_STUB",
        "python_module": "tools/gas_thin_adapter_stubs_v1.py",
        "python_function": "stub_build_watch_ledger",
        "note": "관찰 원장 조립 — Python harness에 직접 대응 없음. stub 생성 필요.",
    },
    {
        "gas_file": "gdf_05_alpha_engines.gs",
        "gas_function": "buildShadowLedger_",
        "responsibility": ["stop_loss", "sizing", "take_profit"],
        "status": "MAPPED",
        "python_module": "src/quant_engine/compute_formula_outputs.py",
        "python_function": "check_sell_price_sanity (shadow_ledger 필드 포함)",
        "note": "그림자 원장(BLOCKED blueprint 분리)은 check_sell_price_sanity의 shadow_ledger 필드 담당",
    },
]


def main() -> int:
    mapped   = [m for m in MIGRATION_MAP if m["status"] == "MAPPED"]
    stubs    = [m for m in MIGRATION_MAP if m["status"] == "NEEDS_STUB"]
    partial  = [m for m in MIGRATION_MAP if m["status"] == "PARTIAL"]

    output = {
        "policy_id": "GAS_THIN_ADAPTER_POLICY_V1",
        "phase": "extract",
        "generated_at": datetime.now().isoformat(),
        "summary": {
            "total_forbidden": len(MIGRATION_MAP),
            "mapped_count": len(mapped),
            "needs_stub_count": len(stubs),
            "partial_count": len(partial),
            "extraction_readiness_pct": round(len(mapped) / len(MIGRATION_MAP) * 100, 1),
        },
        "mapping": MIGRATION_MAP,
        "needs_stub": [
            {"gas_function": m["gas_function"], "python_function": m["python_function"],
             "responsibility": m["responsibility"], "note": m["note"]}
            for m in stubs
        ],
    }

    out = ROOT / "Temp" / "gas_python_migration_map_v1.json"
    out.parent.mkdir(exist_ok=True)
    out.write_text(json.dumps(output, ensure_ascii=False, indent=2), encoding="utf-8")

    print("=== GAS_THIN_ADAPTER_POLICY_V1 Phase-2: Extract ===")
    print(f"총 forbidden 함수  : {len(MIGRATION_MAP)}")
    print(f"  MAPPED           : {len(mapped)}개  (Python 대응 확인)")
    print(f"  NEEDS_STUB       : {len(stubs)}개  (stub 신규 작성 필요)")
    print(f"  PARTIAL          : {len(partial)}개")
    print(f"extraction_readiness: {output['summary']['extraction_readiness_pct']}%")
    print()
    print("── NEEDS_STUB 목록 ──")
    for s in stubs:
        print(f"  {s['gas_file']:45} {s['gas_function']}")
    print()
    print(f"출력: {out}")
    return 0


if __name__ == "__main__":
    sys.exit(main())
