#!/usr/bin/env python3
"""Run clangd diagnostics on every C++ source file in the project.

Scans known source directories for .cpp and .h files, then runs
clangd-query.py diagnostics on each one, reporting any errors or warnings.
"""

import subprocess
import sys
import os
from pathlib import Path

# Directories to scan (relative to project root).
SOURCE_DIRS = [
    "Source/Integration",
    "luprex/cpp/core",
    "luprex/cpp/drv",
    "luprex/cpp/wrap",
    "Plugins/UEWingman/Source/UEWingman/Public",
    "Plugins/UEWingman/Source/UEWingman/Private",
    "Plugins/UEWingman/Source/UEWingman/Handlers",
    "Plugins/UEWingman/Source/UEWingman/HalfBaked",
]

# Files to skip (relative to project root).
SKIP_FILES = set()

EXTENSIONS = {".cpp", ".hpp", ".h", ".c"}


def find_project_root():
    """Walk up from this script's directory to find the project root."""
    d = Path(__file__).resolve().parent.parent
    if (d / "build.py").exists():
        return d
    # Fallback: assume cwd.
    return Path.cwd()


def find_source_files(root):
    """Collect all source files from the known directories."""
    files = []
    for rel_dir in SOURCE_DIRS:
        d = root / rel_dir
        if not d.is_dir():
            print(f"WARNING: directory not found: {rel_dir}", file=sys.stderr)
            continue
        for f in sorted(d.iterdir()):
            if f.is_file() and f.suffix in EXTENSIONS:
                rel = f.relative_to(root)
                if str(rel) not in SKIP_FILES:
                    files.append(rel)
    return files


def run_diagnostics(root, rel_path):
    """Run clangd-query.py diagnostics on a single file. Returns output lines."""
    result = subprocess.run(
        [sys.executable, "tools/clangd-query.py", "diagnostics", str(rel_path)],
        cwd=root,
        capture_output=True,
        text=True,
        timeout=120,
    )
    output = result.stdout.strip()
    if result.returncode != 0 and result.stderr.strip():
        output += "\n" + result.stderr.strip()
    return output


def main():
    root = find_project_root()
    files = find_source_files(root)
    print(f"Found {len(files)} source files across {len(SOURCE_DIRS)} directories.\n")

    total_issues = 0
    files_with_issues = 0

    for i, rel_path in enumerate(files):
        label = f"[{i+1}/{len(files)}] {rel_path}"
        print(f"{label} ... ", end="", flush=True)

        try:
            output = run_diagnostics(root, rel_path)
        except subprocess.TimeoutExpired:
            print("TIMEOUT")
            continue

        if not output or "No problems found" in output or output.strip() == "No diagnostics.":
            print("ok")
        else:
            lines = [l for l in output.splitlines() if l.strip()]
            count = len(lines)
            total_issues += count
            files_with_issues += 1
            print(f"{count} issue(s)")
            for line in lines:
                print(f"  {line}")

    print(f"\nDone. {total_issues} issue(s) in {files_with_issues} file(s) out of {len(files)} checked.")


if __name__ == "__main__":
    main()
