"""Nova Infracost Post-Processor (REQ-187, D-120).

Runs Infracost on `terraform show -json plan.tfplan` (offline, reads plan
JSON, no live AWS). Emits nova.cost.estimated{delta_usd} events. Degrades
gracefully (omits the event, logs a warning) when Infracost CLI is absent
(assumption A6).

run_platform.sh invokes it after the plan stage.
"""

import json
import os
import shutil
import subprocess
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from core.metrics.event_envelope import emit


def _is_infracost_available():
    """Check if the Infracost CLI is on PATH."""
    return shutil.which("infracost") is not None


def estimate(plan_json_path, run_id, contract_id, environment):
    """Run Infracost on a terraform plan JSON. Returns the cost estimate dict.

    Args:
        plan_json_path: path to `terraform show -json plan.tfplan` output
        run_id: the run identifier
        contract_id: the contract UUID
        environment: dev|qa|prod|dr

    Returns:
        {"delta_usd": float, "total_monthly_usd": float, "available": bool}
        or {"available": False} if Infracost is not installed.
    """
    if not _is_infracost_available():
        sys.stderr.write("[infracost] CLI not found — cost.estimated event omitted (A6 degraded mode)\n")
        return {"available": False, "delta_usd": 0.0, "total_monthly_usd": 0.0}

    if not os.path.isfile(plan_json_path):
        sys.stderr.write(f"[infracost] plan JSON not found: {plan_json_path}\n")
        return {"available": False, "delta_usd": 0.0, "total_monthly_usd": 0.0}

    try:
        result = subprocess.run(
            ["infracost", "breakdown", "--path", plan_json_path, "--format", "json"],
            capture_output=True, text=True, timeout=30,
        )
        if result.returncode != 0:
            sys.stderr.write(f"[infracost] CLI failed: {result.stderr[:200]}\n")
            return {"available": False, "delta_usd": 0.0, "total_monthly_usd": 0.0}

        breakdown = json.loads(result.stdout)
        delta = float(breakdown.get("diffTotalMonthlyCost", 0.0))
        total = float(breakdown.get("totalMonthlyCost", 0.0))
        estimate_data = {"available": True, "delta_usd": delta, "total_monthly_usd": total}

        emit("nova.cost.estimated", run_id, environment, estimate_data, contract_id=contract_id)
        return estimate_data
    except Exception as exc:
        sys.stderr.write(f"[infracost] error: {exc}\n")
        return {"available": False, "delta_usd": 0.0, "total_monthly_usd": 0.0}


if __name__ == "__main__":
    if len(sys.argv) < 5:
        print("usage: infracost_adapter.py <plan_json_path> <run_id> <contract_id> <environment>", file=sys.stderr)
        sys.exit(2)
    est = estimate(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
    print(json.dumps(est, indent=2))