#!/usr/bin/env python3
"""Run gitleaks over every cloned repo (full history) — engagement one-off.

Per-repo report: L3_history_gitleaks/<repo>.json. Resume-safe (skips existing).
Aggregate: L3_history_secrets.json (all findings with repo attribution).
"""
import json, subprocess, time
from pathlib import Path

ROOT = Path('/root/ir-assessment/redteam/gitlab_npontutechnologies_com')
REPOS = ROOT / 'repos'
OUTDIR = ROOT / 'L3_history_gitleaks'
AGG = ROOT / 'L3_history_secrets.json'
LOG = ROOT / 'gitleaks_run.log'

def main():
    OUTDIR.mkdir(exist_ok=True)
    repos = sorted(REPOS.glob('*.git'))
    log = LOG.open('a')
    log.write(f'=== gitleaks run {time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime())} repos={len(repos)} ===\n')
    all_findings = []
    for i, repo in enumerate(repos, 1):
        name = repo.name[:-4]  # strip .git
        report = OUTDIR / f'{name}.json'
        if report.exists():
            try:
                all_findings += [{**f, 'repo': name} for f in json.loads(report.read_text())]
            except Exception:
                pass
            continue
        t0 = time.time()
        r = subprocess.run(
            ['gitleaks', 'git', '--report-path', str(report), '--report-format', 'json',
             '--log-level', 'warn', str(repo)],
            capture_output=True, text=True, timeout=900)
        dt = time.time() - t0
        try:
            findings = json.loads(report.read_text()) if report.exists() else []
        except Exception:
            findings = []
        all_findings += [{**f, 'repo': name} for f in findings]
        line = f'[{i}/{len(repos)}] {name}: {len(findings)} findings ({dt:.0f}s, rc={r.returncode})'
        print(line, flush=True); log.write(line + '\n'); log.flush()
    AGG.write_text(json.dumps(all_findings, ensure_ascii=False, indent=1))
    line = f'=== done: {len(all_findings)} total findings -> {AGG} ==='
    print(line); log.write(line + '\n'); log.close()

if __name__ == '__main__':
    main()
