# CWE-407 Scan Makefile
# Tracks all scan targets, results, and triage state.
# Results are files — make skips targets that are already up to date.
#
# Usage:
#   make scan-networkx          # single target
#   make scan-critical          # all critical-priority targets
#   make scan-networking        # all networking targets
#   make scan-scientific        # all scientific computing targets
#   make scan-databases         # all database targets
#   make scan-eda               # all EDA/chip targets
#   make scan-web-infra         # all web infrastructure targets
#   make scan-all               # everything
#   make report                 # summarize all completed results
#   make clean-results          # remove all result files (re-run everything)
#
# Prerequisites:
#   ~/.unsandbox/accounts.csv must exist (see: un key)
#   Row 0: portal-playground, Row 1: russ-test (for -j2 parallel)
#   UN := path to un binary (default: ~/git/un-inception/build/un)

UN         ?= $(HOME)/git/un-inception/build/un
RESULTS    := scan-results
SCANS      := scans

# Account slots from ~/.unsandbox/accounts.csv (0-based index)
# -j2 uses both slots in parallel — no env vars needed
ACCT1      ?= 1
ACCT2      ?= 0

# Network mode: semitrusted required for targets that git clone
NET_CLONE  := -n semitrusted
NET_NONE   :=

# ── Result file targets ──────────────────────────────────────────────────────
# Each target produces scan-results/<name>.txt
# Make tracks freshness: re-run only if .sh is newer than .txt

$(RESULTS)/frrouting.txt: $(SCANS)/frrouting.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/networkx.txt: $(SCANS)/networkx.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/exabgp.txt: $(SCANS)/exabgp.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/postgresql.txt: $(SCANS)/postgresql.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/verilator.txt: $(SCANS)/verilator.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/yosys.txt: $(SCANS)/yosys.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/sqlite.txt: $(SCANS)/sqlite.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/mysql.txt: $(SCANS)/mysql.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/bird.txt: $(SCANS)/bird.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/onos.txt: $(SCANS)/onos.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/opendaylight.txt: $(SCANS)/opendaylight.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/v8.txt: $(SCANS)/v8.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/spidermonkey.txt: $(SCANS)/spidermonkey.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/bazel.txt: $(SCANS)/bazel.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/kicad.txt: $(SCANS)/kicad.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/gnu-octave.txt: $(SCANS)/gnu-octave.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/php-zend.txt: $(SCANS)/php-zend.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/redis.txt: $(SCANS)/redis.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/varnish.txt: $(SCANS)/varnish.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/nginx.txt: $(SCANS)/nginx.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/apache2.txt: $(SCANS)/apache2.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/memcached.txt: $(SCANS)/memcached.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/ant.txt: $(SCANS)/ant.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/sbt.txt: $(SCANS)/sbt.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/bundler.txt: $(SCANS)/bundler.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/duckdb.txt: $(SCANS)/duckdb.sh
	$(UN) --account $(ACCT2) $(NET_CLONE) $< | tee $@

$(RESULTS)/composer.txt: $(SCANS)/composer.sh
	$(UN) --account $(ACCT1) $(NET_CLONE) $< | tee $@

$(RESULTS)/full-43lang.txt: ../tools/unsandbox-scan.sh
	$(UN) --account $(ACCT1) $(NET_NONE) $< | tee $@

# ── Grouped phony targets ────────────────────────────────────────────────────

.PHONY: scan-critical scan-networking scan-scientific scan-databases \
        scan-eda scan-compilers scan-web-infra scan-package-managers scan-all \
        scan-frrouting scan-networkx scan-exabgp scan-postgresql scan-sqlite \
        scan-verilator scan-yosys scan-mysql scan-bird scan-onos \
        scan-opendaylight scan-v8 scan-spidermonkey scan-bazel \
        scan-kicad scan-gnu-octave scan-php-zend scan-redis \
        scan-varnish scan-nginx scan-apache2 scan-memcached \
        scan-ant scan-sbt scan-bundler scan-duckdb scan-composer \
        scan-43lang report clean-results help

# Convenience aliases
scan-frrouting:    $(RESULTS)/frrouting.txt
scan-networkx:     $(RESULTS)/networkx.txt
scan-exabgp:       $(RESULTS)/exabgp.txt
scan-postgresql:   $(RESULTS)/postgresql.txt
scan-sqlite:       $(RESULTS)/sqlite.txt
scan-verilator:    $(RESULTS)/verilator.txt
scan-yosys:        $(RESULTS)/yosys.txt
scan-mysql:        $(RESULTS)/mysql.txt
scan-bird:         $(RESULTS)/bird.txt
scan-onos:         $(RESULTS)/onos.txt
scan-opendaylight: $(RESULTS)/opendaylight.txt
scan-v8:           $(RESULTS)/v8.txt
scan-spidermonkey: $(RESULTS)/spidermonkey.txt
scan-bazel:        $(RESULTS)/bazel.txt
scan-kicad:        $(RESULTS)/kicad.txt
scan-gnu-octave:   $(RESULTS)/gnu-octave.txt
scan-php-zend:     $(RESULTS)/php-zend.txt
scan-redis:        $(RESULTS)/redis.txt
scan-varnish:      $(RESULTS)/varnish.txt
scan-nginx:        $(RESULTS)/nginx.txt
scan-apache2:      $(RESULTS)/apache2.txt
scan-memcached:    $(RESULTS)/memcached.txt
scan-ant:          $(RESULTS)/ant.txt
scan-sbt:          $(RESULTS)/sbt.txt
scan-bundler:      $(RESULTS)/bundler.txt
scan-duckdb:       $(RESULTS)/duckdb.txt
scan-composer:     $(RESULTS)/composer.txt
scan-43lang:       $(RESULTS)/full-43lang.txt

# Priority groups
scan-critical: scan-frrouting scan-networkx scan-exabgp

scan-networking: \
	scan-frrouting scan-exabgp scan-bird scan-onos scan-opendaylight

scan-scientific: \
	scan-networkx scan-gnu-octave

scan-databases: \
	scan-postgresql scan-sqlite scan-mysql

scan-eda: \
	scan-verilator scan-yosys scan-kicad

scan-compilers: \
	scan-v8 scan-spidermonkey scan-bazel

scan-web-infra: \
	scan-php-zend scan-redis scan-varnish scan-nginx scan-apache2 scan-memcached

scan-package-managers: \
	scan-ant scan-sbt scan-bundler scan-duckdb scan-composer

scan-all: \
	scan-critical scan-networking scan-scientific \
	scan-databases scan-eda scan-compilers scan-web-infra scan-43lang

# ── Report ───────────────────────────────────────────────────────────────────

report:
	@echo ""
	@echo "═══════════════════════════════════════════════════════"
	@echo "  CWE-407 Scan Report  —  $(shell date -u +%Y-%m-%dT%H:%M:%SZ)"
	@echo "═══════════════════════════════════════════════════════"
	@echo ""
	@total=0; \
	for f in $(RESULTS)/*.txt; do \
	  [ -f "$$f" ] || continue; \
	  target=$$(basename $$f .txt); \
	  hits=$$(grep -c '^CANDIDATE' "$$f" 2>/dev/null || true); \
	  hits=$${hits:-0}; \
	  total=$$((total + hits)); \
	  if [ "$$hits" -gt 0 ]; then \
	    printf "  %-20s  %3d candidates\n" "$$target" "$$hits"; \
	    grep '^CANDIDATE' "$$f" | head -3 | sed 's/^/    /'; \
	  else \
	    printf "  %-20s  CLEAN\n" "$$target"; \
	  fi; \
	  echo ""; \
	done; \
	echo "  Total candidates: $$total"
	@echo "═══════════════════════════════════════════════════════"
	@echo ""

# ── Maintenance ──────────────────────────────────────────────────────────────

clean-results:
	rm -f $(RESULTS)/*.txt
	@echo "All result files removed — next make scan-* will re-run from scratch"

help:
	@echo ""
	@echo "Targets:"
	@echo "  scan-critical      frrouting, networkx, exabgp (highest impact)"
	@echo "  scan-networking    all routing/SDN targets"
	@echo "  scan-scientific    networkx, gnu-octave"
	@echo "  scan-databases     postgresql, mysql"
	@echo "  scan-eda           verilator, yosys, kicad"
	@echo "  scan-compilers     v8, spidermonkey, bazel"
	@echo "  scan-web-infra     php-zend, redis, varnish, nginx, apache2, memcached"
	@echo "  scan-43lang        full golden-image scan (no clone needed)"
	@echo "  scan-all           everything"
	@echo "  report             summarize all completed results"
	@echo "  clean-results      force re-run of all scans"
	@echo ""
	@echo "Variables:"
	@echo "  UN=path     path to un binary (default: ~/git/un-inception/build/un)"
	@echo "  ACCT1=N     primary account index in ~/.unsandbox/accounts.csv (default: 1)"
	@echo "  ACCT2=N     secondary account index (default: 0, used for -j2 parallel)"
	@echo ""
	@echo "Parallel execution (uses both account slots):"
	@echo "  make -j2 scan-critical"
	@echo ""
