"""Wraps remote_probe.py logic for running probes on this node."""
from __future__ import annotations

import json
import logging
import sqlite3
import subprocess
import sys
import tempfile
import time
from pathlib import Path
from typing import Any, Dict, List, Optional

logger = logging.getLogger(__name__)

# Path to the self-contained remote probe script
PROBE_SCRIPT = Path(__file__).resolve().parents[2] / "scripts" / "remote_probe.py"


def run_probes(
    iterations: int = 20,
    output_db: Optional[str] = None,
    kernel_types: Optional[List[str]] = None,
) -> Dict[str, Any]:
    """Run hardware probes and return results summary.

    Args:
        iterations: Number of iterations per probe
        output_db: Path to output SQLite DB (temp file if None)
        kernel_types: Optional list of kernel types to probe (None = all)

    Returns:
        Dict with data_points, invariants, db_path, duration_s
    """
    if output_db is None:
        output_db = tempfile.mktemp(suffix=".db", prefix="probe_")

    if not PROBE_SCRIPT.exists():
        logger.error("Probe script not found: %s", PROBE_SCRIPT)
        return {"error": f"Probe script not found: {PROBE_SCRIPT}"}

    cmd = [sys.executable, str(PROBE_SCRIPT),
           "--iterations", str(iterations),
           "--output", output_db]
    if kernel_types:
        cmd.extend(["--kernels", ",".join(kernel_types)])

    logger.info("Running probes: %s", " ".join(cmd))
    t0 = time.time()

    try:
        result = subprocess.run(
            cmd, capture_output=True, text=True, timeout=600
        )
        duration = time.time() - t0

        if result.returncode != 0:
            logger.error("Probe failed (rc=%d): %s", result.returncode, result.stderr[-500:])
            return {"error": result.stderr[-500:], "duration_s": duration}

        # Count results
        data_points = 0
        invariants = 0
        if Path(output_db).exists():
            conn = sqlite3.connect(output_db)
            try:
                data_points = conn.execute("SELECT COUNT(*) FROM data_points").fetchone()[0]
            except Exception:
                pass
            try:
                invariants = conn.execute("SELECT COUNT(*) FROM invariants").fetchone()[0]
            except Exception:
                pass
            conn.close()

        logger.info("Probes complete: %d data points, %d invariants in %.1fs",
                     data_points, invariants, duration)
        return {
            "data_points": data_points,
            "invariants": invariants,
            "db_path": output_db,
            "duration_s": round(duration, 1),
        }
    except subprocess.TimeoutExpired:
        return {"error": "Probe timed out after 600s"}
    except Exception as e:
        return {"error": str(e)}


def extract_atlas_data(db_path: str) -> Dict[str, List[Dict]]:
    """Extract data points and invariants from a probe DB for syncing."""
    if not Path(db_path).exists():
        return {"data_points": [], "invariants": []}

    conn = sqlite3.connect(db_path)
    conn.row_factory = sqlite3.Row

    data_points = []
    try:
        for row in conn.execute("SELECT * FROM data_points"):
            data_points.append(dict(row))
    except Exception:
        pass

    invariants = []
    try:
        for row in conn.execute("SELECT * FROM invariants"):
            invariants.append(dict(row))
    except Exception:
        pass

    conn.close()
    return {"data_points": data_points, "invariants": invariants}
