"""IdeaSweeper local project scanner.

Scans your project folders for development footprints (git, frameworks,
deploy configuration) and writes a lightweight c_drive_metadata.json you
drag into the IdeaSweeper intake zone. Nothing is uploaded anywhere; only
folder names and which marker files exist are recorded, never file contents.

Usage:
    py scanner/scan_projects.py                       # scans the default roots
    py scanner/scan_projects.py C:/some/folder ...    # scans the given roots
    py scanner/scan_projects.py --out my.json C:/dev  # custom output path
"""

import argparse
import json
import os
import sys
from datetime import datetime, timezone

_HOME = os.path.expanduser("~")
DEFAULT_ROOTS = [
    os.path.join(_HOME, "Projects"),
    os.path.join(_HOME, "Documents", "GitHub"),
    os.path.join(_HOME, "dev"),
    r"C:\dev",
]

SKIP_NAMES = {"node_modules", "__pycache__", "dist", "build", ".venv", "venv"}


def detect(folder_path):
    """Return (badges, is_deployed) from marker files in one project folder."""
    badges = []
    is_deployed = False

    def has(*parts):
        return os.path.exists(os.path.join(folder_path, *parts))

    if has(".git"):
        badges.append("Git")
    if has("package.json"):
        framework = "Node"
        try:
            with open(os.path.join(folder_path, "package.json"), encoding="utf-8") as f:
                pkg = json.load(f)
            deps = {}
            deps.update(pkg.get("dependencies") or {})
            deps.update(pkg.get("devDependencies") or {})
            if "next" in deps:
                framework = "Next.js"
            elif "react" in deps:
                framework = "React"
            elif "vite" in deps:
                framework = "Vite"
        except (OSError, ValueError):
            pass
        badges.append(framework)
    if has("requirements.txt") or has("pyproject.toml"):
        badges.append("Python")
    if has("wrangler.toml") or has("wrangler.json") or has("wrangler.jsonc"):
        badges.append("Cloudflare")
        is_deployed = True
    if has("functions") and "Cloudflare" not in badges and has("_headers"):
        badges.append("Cloudflare")
        is_deployed = True
    if has(".vercel", "project.json"):
        badges.append("Vercel")
        is_deployed = True
    if has("CNAME"):
        badges.append("GitHub Pages")
        is_deployed = True
    if has("netlify.toml"):
        badges.append("Netlify")
        is_deployed = True

    return badges, is_deployed


def scan_root(root):
    projects = []
    if not os.path.isdir(root):
        print(f"Skipping missing root: {root}")
        return projects
    for name in sorted(os.listdir(root)):
        if name.startswith(".") or name.lower() in SKIP_NAMES:
            continue
        folder_path = os.path.join(root, name)
        if not os.path.isdir(folder_path):
            continue
        badges, is_deployed = detect(folder_path)
        try:
            mtime = os.path.getmtime(folder_path)
            last_modified = datetime.fromtimestamp(mtime, tz=timezone.utc).isoformat()
        except OSError:
            last_modified = None
        projects.append(
            {
                "name": name.replace("-", " ").replace("_", " ").strip().title(),
                "path": folder_path,
                "badges": badges,
                "isDeployed": is_deployed,
                "hasCode": bool(badges),
                "lastModified": last_modified,
            }
        )
    return projects


def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("roots", nargs="*", default=None, help="Folders to scan")
    parser.add_argument("--out", default="c_drive_metadata.json", help="Output file")
    args = parser.parse_args()

    roots = args.roots or DEFAULT_ROOTS
    projects = []
    for root in roots:
        projects.extend(scan_root(root))

    payload = {
        "generatedAt": datetime.now(tz=timezone.utc).isoformat(),
        "roots": roots,
        "projects": projects,
    }
    with open(args.out, "w", encoding="utf-8") as f:
        json.dump(payload, f, indent=2)
    print(f"Wrote {len(projects)} projects to {os.path.abspath(args.out)}")
    return 0


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