"""Gitleaks scanner integration — secret scanning via subprocess."""

from __future__ import annotations

import json
import logging
import subprocess
import tempfile
from pathlib import Path
from typing import Any

from secagent.scanners.base_scanner import BaseScanner

logger = logging.getLogger(__name__)

# GitHub coordinates for auto-install
_GITHUB_OWNER = "gitleaks"
_GITHUB_REPO = "gitleaks"


class GitleaksScanner(BaseScanner):
    """Runs `gitleaks detect` and returns parsed JSON findings."""

    name = "gitleaks"
    github_owner = _GITHUB_OWNER
    github_repo = _GITHUB_REPO

    def run(self, target: Path) -> list[dict[str, Any]]:
        exe = self.get_executable()
        if not exe:
            return []

        with tempfile.NamedTemporaryFile(
            suffix=".json", delete=False, mode="w"
        ) as tmp:
            report_path = tmp.name

        cmd = [
            exe,
            "detect",
            "--source",
            str(target),
            "--report-format",
            "json",
            "--report-path",
            report_path,
            "--no-git",
            "--exit-code",
            "0",
        ]

        logger.info("Running: %s", " ".join(cmd))

        try:
            subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=120,
                check=False,
            )

            report = Path(report_path)
            if report.exists():
                content = report.read_text(encoding="utf-8").strip()
                if content:
                    findings = json.loads(content)
                    if isinstance(findings, list):
                        return findings
            return []

        except subprocess.TimeoutExpired:
            logger.error("Gitleaks timed out after 120 s")
            return []
        except (json.JSONDecodeError, OSError) as exc:
            logger.error("Gitleaks output parsing failed: %s", exc)
            return []
        finally:
            Path(report_path).unlink(missing_ok=True)
