# Tests + benchmarks for CWE-407 defects across javac and Minecraft
#
# javac (tickets 0001–0005):
#   make unit             — 6 self-contained unit suites (no JDK internals)
#   make integration      — requires --add-exports jdk.compiler
#   make functional       — requires ToolProvider (JDK, not JRE)
#   make all              — unit + integration + functional
#   make bench            — before/after timing for 0001 only (Tarjan)
#   make bench-all        — before/after timing for all five javac defects
#   make bench-real       — patches GraphUtils.java, runs integration before+after
#
# Minecraft (gumyum paper):
#   make bench-mc-server  — DependencySorter depth scaling (mc-0001)
#   make bench-max        — BenchMax extreme-scale (javac + MC + Create)
#   make bench-gumyum     — all Minecraft + Create benchmarks
#   make bench-everything — javac + Minecraft + BenchMax
#
# Three-tier enriched-minecraft benchmarks (real server):
#   make bench-unpatched  — control: vanilla jar, depth-16 (defect present)
#   make bench-mitigated  — fix applied: patched jar, depth-16 (same game)
#   make bench-enriched   — new territory: patched jar, depth-24 / 300 NS
#   make bench-three-tier — run all three in sequence, print summary
#   make bench-elytra     — 30 players, elytra + fireworks, all directions (final)
#
# Human play-test (server stays up, connect with Minecraft client):
#   make play-unpatched   — localhost:25565
#   make play-mitigated   — localhost:25566
#   make play-enriched    — localhost:25567  (enriched-minecraft experience)
#
#   make clean            — remove compiled classes

JAVA    := java
# Use jdk.compiler module directly — system javac binary may not be installed.
JAVAC   := java -m jdk.compiler/com.sun.tools.javac.Main
EXPORTS := --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

# JDK 25 for Minecraft class file version 69 compatibility
JAVA25  := /tmp/jdk25/bin/java
JAVAC25 := /tmp/jdk25/bin/javac
GUAVA   := /tmp/guava.jar

SUPPORT_ALL := support/TarjanAlgorithm.java \
               support/FindNodeAlgorithm.java \
               support/ClosureAlgorithm.java \
               support/TopoSorterAlgorithm.java \
               support/DependencyListAlgorithm.java \
               support/BoundSetAlgorithm.java \
               support/PostgresqlVarDedupAlgorithm.java \
               support/PostgresqlExprMembershipAlgorithm.java \
               support/PostgresqlJoinMergeAlgorithm.java \
               support/MongodbIndexPlannerAlgorithm.java \
               support/MongodbPipelineAlgorithm.java \
               support/SwiplAlgorithm.java

.PHONY: all unit integration functional bench bench-all bench-real clean \
        unit-tarjan unit-findnode unit-closure unit-toposort unit-deplist unit-boundset \
        unit-psql-0002 unit-psql-0003 unit-psql-0004 bench-psql \
        unit-mongo-0001 unit-mongo-0002 bench-mongo \
        unit-swipl bench-swipl \
        unit-hive unit-spark unit-luigi \
        unit-frrouting-0002 unit-tor-0001 \
        unit-solc-0001 unit-solc-0002 unit-buildkit-0001 \
        unit-kafka unit-spring unit-presto unit-webpack \
        unit-onos-0001 unit-bird unit-bazel unit-odl-0001 unit-httpd-0001 unit-kicad-0001 \
        unit-v8-0001 unit-spidermonkey-0001 unit-llvm-0002 unit-octave-0001 \
        unit-rabbitmq unit-cfengine unit-terraform unit-ansible \
        unit-networkx unit-jenkins unit-maven-extra \
        unit-tinkerpop-0001 \
        bench-mc-server bench-max bench-gumyum bench-everything bench-loadsim bench-elytra \
        bench-unpatched bench-mitigated bench-enriched bench-three-tier \
        play-unpatched play-mitigated play-enriched \
        workbench workbench-build workbench-patched workbench-verify

all: unit integration functional

# ── Unit ──────────────────────────────────────────────────────────────────────
# Self-contained — no jdk.compiler dependency.
# Six suites, one per defect.

unit: unit-tarjan unit-findnode unit-closure unit-toposort unit-deplist unit-boundset \
      unit-psql-0002 unit-psql-0003 unit-psql-0004 \
      unit-mongo-0001 unit-mongo-0002 \
      unit-swipl \
      unit-hive unit-spark unit-luigi \
      unit-frrouting-0002 unit-tor-0001 \
      unit-solc-0001 unit-solc-0002 unit-buildkit-0001 \
      unit-kafka unit-spring unit-presto unit-webpack \
      unit-onos-0001 unit-bird unit-bazel unit-odl-0001 unit-httpd-0001 unit-kicad-0001 \
      unit-v8-0001 unit-spidermonkey-0001 unit-llvm-0002 unit-octave-0001 \
      unit-rabbitmq \
      unit-cfengine unit-terraform unit-ansible \
      unit-networkx unit-jenkins unit-maven-extra \
      unit-tinkerpop-0001

unit-tarjan: unit/TarjanComplexityTest.class
	@echo ""
	@echo "=== UNIT 0001: TarjanComplexityTest ==="
	$(JAVA) -cp . unit.TarjanComplexityTest

unit/TarjanComplexityTest.class: support/TarjanAlgorithm.java unit/TarjanComplexityTest.java
	$(JAVAC) -cp . support/TarjanAlgorithm.java unit/TarjanComplexityTest.java

unit-findnode: unit/FindNodeComplexityTest.class
	@echo ""
	@echo "=== UNIT 0002a: FindNodeComplexityTest ==="
	$(JAVA) -cp . unit.FindNodeComplexityTest

unit/FindNodeComplexityTest.class: support/FindNodeAlgorithm.java unit/FindNodeComplexityTest.java
	$(JAVAC) -cp . support/FindNodeAlgorithm.java unit/FindNodeComplexityTest.java

unit-closure: unit/ClosureComplexityTest.class
	@echo ""
	@echo "=== UNIT 0002b: ClosureComplexityTest ==="
	$(JAVA) -cp . unit.ClosureComplexityTest

unit/ClosureComplexityTest.class: support/ClosureAlgorithm.java unit/ClosureComplexityTest.java
	$(JAVAC) -cp . support/ClosureAlgorithm.java unit/ClosureComplexityTest.java

unit-toposort: unit/TopoSorterComplexityTest.class
	@echo ""
	@echo "=== UNIT 0003: TopoSorterComplexityTest ==="
	$(JAVA) -cp . unit.TopoSorterComplexityTest

unit/TopoSorterComplexityTest.class: support/TopoSorterAlgorithm.java unit/TopoSorterComplexityTest.java
	$(JAVAC) -cp . support/TopoSorterAlgorithm.java unit/TopoSorterComplexityTest.java

unit-deplist: unit/DependencyListComplexityTest.class
	@echo ""
	@echo "=== UNIT 0004: DependencyListComplexityTest ==="
	$(JAVA) -cp . unit.DependencyListComplexityTest

unit/DependencyListComplexityTest.class: support/DependencyListAlgorithm.java unit/DependencyListComplexityTest.java
	$(JAVAC) -cp . support/DependencyListAlgorithm.java unit/DependencyListComplexityTest.java

unit-boundset: unit/BoundSetComplexityTest.class
	@echo ""
	@echo "=== UNIT 0005: BoundSetComplexityTest ==="
	$(JAVA) -cp . unit.BoundSetComplexityTest

unit/BoundSetComplexityTest.class: support/BoundSetAlgorithm.java unit/BoundSetComplexityTest.java
	$(JAVAC) -cp . support/BoundSetAlgorithm.java unit/BoundSetComplexityTest.java

# ── PostgreSQL unit tests (0002/0003/0004) ─────────────────────────────────────

support/PostgresqlVarDedupAlgorithm.class: support/PostgresqlVarDedupAlgorithm.java
	$(JAVAC) -cp . support/PostgresqlVarDedupAlgorithm.java

support/PostgresqlExprMembershipAlgorithm.class: support/PostgresqlExprMembershipAlgorithm.java
	$(JAVAC) -cp . support/PostgresqlExprMembershipAlgorithm.java

support/PostgresqlJoinMergeAlgorithm.class: support/PostgresqlJoinMergeAlgorithm.java
	$(JAVAC) -cp . support/PostgresqlJoinMergeAlgorithm.java

unit-psql-0002: support/PostgresqlVarDedupAlgorithm.class
	@echo ""
	@echo "=== UNIT postgresql-0002: VarDedup (preptlist.c tlist_member) ==="
	$(JAVA) -ea -cp . support.PostgresqlVarDedupAlgorithm

unit-psql-0003: support/PostgresqlExprMembershipAlgorithm.class
	@echo ""
	@echo "=== UNIT postgresql-0003: ExprMembership (equivclass.c list_member) ==="
	$(JAVA) -ea -cp . support.PostgresqlExprMembershipAlgorithm

unit-psql-0004: support/PostgresqlJoinMergeAlgorithm.class
	@echo ""
	@echo "=== UNIT postgresql-0004: JoinMerge (analyzejoins.c list_member) ==="
	$(JAVA) -ea -cp . support.PostgresqlJoinMergeAlgorithm

bench/PostgresqlBenchmark.class: bench/PostgresqlBenchmark.java \
    support/PostgresqlVarDedupAlgorithm.class \
    support/PostgresqlExprMembershipAlgorithm.class \
    support/PostgresqlJoinMergeAlgorithm.class
	$(JAVAC) -cp . bench/PostgresqlBenchmark.java

bench-psql: bench/PostgresqlBenchmark.class
	@echo ""
	@echo "=== BENCH postgresql-0002/0003/0004: algorithm micro-benchmarks ==="
	$(JAVA) -cp . bench.PostgresqlBenchmark

# SQL functional tests — requires a running PostgreSQL instance
# Usage: make functional-psql PSQL="psql -U postgres"
PSQL := psql
functional-psql:
	@echo ""
	@echo "=== FUNCTIONAL postgresql-0002/0003/0004: SQL correctness tests ==="
	$(PSQL) -v ON_ERROR_STOP=1 -f sql/postgresql-0002-0004.sql

# ── MongoDB unit tests (0001/0002) ─────────────────────────────────────────────

support/MongodbIndexPlannerAlgorithm.class: support/MongodbIndexPlannerAlgorithm.java
	$(JAVAC) -cp . support/MongodbIndexPlannerAlgorithm.java

support/MongodbPipelineAlgorithm.class: support/MongodbPipelineAlgorithm.java
	$(JAVAC) -cp . support/MongodbPipelineAlgorithm.java

unit-mongo-0001: support/MongodbIndexPlannerAlgorithm.class
	@echo ""
	@echo "=== UNIT mongodb-0001/0003: IndexPlanner (planner_ixselect.cpp RelevantTag + plan_enumerator.cpp) ==="
	$(JAVA) -ea -cp . support.MongodbIndexPlannerAlgorithm

unit-mongo-0002: support/MongodbPipelineAlgorithm.class
	@echo ""
	@echo "=== UNIT mongodb-0002/0004: Pipeline (streaming_group + unpack_bucket) ==="
	$(JAVA) -ea -cp . support.MongodbPipelineAlgorithm

bench/MongodbBenchmark.class: bench/MongodbBenchmark.java \
    support/MongodbIndexPlannerAlgorithm.class \
    support/MongodbPipelineAlgorithm.class
	$(JAVAC) -cp . bench/MongodbBenchmark.java

bench-mongo: bench/MongodbBenchmark.class
	@echo ""
	@echo "=== BENCH mongodb-0001/0002/0003/0004: algorithm micro-benchmarks ==="
	$(JAVA) -cp . bench.MongodbBenchmark

# ── SWI-Prolog unit test (swipl-0001/0002/0003) ───────────────────────────────

support/SwiplAlgorithm.class: support/SwiplAlgorithm.java
	$(JAVAC) -cp . support/SwiplAlgorithm.java

unit-swipl: support/SwiplAlgorithm.class
	@echo ""
	@echo "=== UNIT swipl-0001/0002/0003: ugraphs.pl top_sort + aggregate.pl free_variables + clp_distinct ==="
	$(JAVA) -ea -cp . support.SwiplAlgorithm

bench-swipl: support/SwiplAlgorithm.class
	@echo ""
	@echo "=== BENCH swipl-0001/0002/0003: algorithm micro-benchmarks ==="
	$(JAVA) -cp . support.SwiplAlgorithm

# ── Hive unit tests (hive-0001/0002) ──────────────────────────────────────────

unit/HiveGenMRSeenOpsTest.class: ../defects/hive/unit/HiveGenMRSeenOpsTest.java
	$(JAVAC) -cp . -d . ../defects/hive/unit/HiveGenMRSeenOpsTest.java

unit-hive: unit/HiveGenMRSeenOpsTest.class
	@echo ""
	@echo "=== UNIT hive-0001/0002: GenMRProcContext seenOps (ArrayList→HashSet) ==="
	$(JAVA) -ea -cp . unit.HiveGenMRSeenOpsTest

# ── Spark unit test (spark-0001) ──────────────────────────────────────────────

unit/SparkAnalyzerWindowAggTest.class: ../defects/spark/unit/SparkAnalyzerWindowAggTest.java
	$(JAVAC) -cp . -d . ../defects/spark/unit/SparkAnalyzerWindowAggTest.java

unit-spark: unit/SparkAnalyzerWindowAggTest.class
	@echo ""
	@echo "=== UNIT spark-0001: Analyzer seenWindowAggregates (ArrayBuffer→LinkedHashSet) ==="
	$(JAVA) -ea -cp . unit.SparkAnalyzerWindowAggTest

# ── Luigi unit test (luigi-0001) ──────────────────────────────────────────────

unit-luigi:
	@echo ""
	@echo "=== UNIT luigi-0001: dfs_paths path_set (set(path) rebuild→O(1)) ==="
	python3 -m unittest discover -s ../defects/luigi/unit -p "*.py" -v

# ── FRRouting unit test (frrouting-0002) ──────────────────────────────────────

unit/FrroutingOspfVertexParentTest.class: ../defects/frrouting/unit/FrroutingOspfVertexParentTest.java
	$(JAVAC) -cp . -d . ../defects/frrouting/unit/FrroutingOspfVertexParentTest.java

unit-frrouting-0002: unit/FrroutingOspfVertexParentTest.class
	@echo ""
	@echo "=== UNIT frrouting-0002: ospf_vertex_add_parent listnode_lookup→hash (199.5x at V=400) ==="
	$(JAVA) -ea -cp . unit.FrroutingOspfVertexParentTest

# ── Tor unit test (tor-0001) ──────────────────────────────────────────────────

unit/TorRouterlistTest.class: ../defects/tor/unit/TorRouterlistTest.java
	$(JAVAC) -cp . -d . ../defects/tor/unit/TorRouterlistTest.java

unit-tor-0001: unit/TorRouterlistTest.class
	@echo ""
	@echo "=== UNIT tor-0001: routerlist fingerprint lookup smartlist→digestset (200.5x at R=400) ==="
	$(JAVA) -ea -cp . unit.TorRouterlistTest

# ── Solidity compiler unit tests (solc-0001/0002) ─────────────────────────────

unit/SolcCallGraphCycleTest.class: ../defects/solc/unit/SolcCallGraphCycleTest.java
	$(JAVAC) -cp . -d . ../defects/solc/unit/SolcCallGraphCycleTest.java

unit-solc-0001: unit/SolcCallGraphCycleTest.class
	@echo ""
	@echo "=== UNIT solc-0001: CallGraphCycleFinder currentPath std::find→unordered_set (15.5x at F=D=32) ==="
	$(JAVA) -ea -cp . unit.SolcCallGraphCycleTest

unit/SolcAssemblyRjumpTest.class: ../defects/solc/unit/SolcAssemblyRjumpTest.java
	$(JAVAC) -cp . -d . ../defects/solc/unit/SolcAssemblyRjumpTest.java

unit-solc-0002: unit/SolcAssemblyRjumpTest.class
	@echo ""
	@echo "=== UNIT solc-0002: Assembly RJUMP std::find→unordered_map index (25.3x at J=N=100) ==="
	$(JAVA) -ea -cp . unit.SolcAssemblyRjumpTest

# ── BuildKit unit test (buildkit-0001) ────────────────────────────────────────

unit/BuildkitHasLinkTest.class: ../defects/buildkit/unit/BuildkitHasLinkTest.java
	$(JAVAC) -cp . -d . ../defects/buildkit/unit/BuildkitHasLinkTest.java

unit-buildkit-0001: unit/BuildkitHasLinkTest.class
	@echo ""
	@echo "=== UNIT buildkit-0001: HasLink slices.Contains→map[string]struct{} (100x at K=L=100) ==="
	$(JAVA) -ea -cp . unit.BuildkitHasLinkTest

# ── Kafka unit tests (kafka-0001/0002) ────────────────────────────────────────

unit/KafkaStickyAssignorTest.class: ../defects/kafka/unit/KafkaStickyAssignorTest.java
	$(JAVAC) -cp . -d . ../defects/kafka/unit/KafkaStickyAssignorTest.java

unit-kafka: unit/KafkaStickyAssignorTest.class
	@echo ""
	@echo "=== UNIT kafka-0001/0002: StickyAssignor isBalanced/maybeAssign (List→HashSet) ==="
	$(JAVA) -ea -cp . unit.KafkaStickyAssignorTest

# ── Spring unit tests (spring-0001/0002) ──────────────────────────────────────

unit/SpringBeanFactoryTest.class: ../defects/spring/unit/SpringBeanFactoryTest.java
	$(JAVAC) -cp . -d . ../defects/spring/unit/SpringBeanFactoryTest.java

unit-spring: unit/SpringBeanFactoryTest.class
	@echo ""
	@echo "=== UNIT spring-0001/0002: BeanFactoryUtils/ImportStack (ArrayList→LinkedHashSet) ==="
	$(JAVA) -ea -cp . unit.SpringBeanFactoryTest

# ── Presto unit tests (presto-0001 through 0004) ──────────────────────────────

unit/PrestoDerefPushdownTest.class: ../defects/presto/unit/PrestoDerefPushdownTest.java
	$(JAVAC) -cp . -d . ../defects/presto/unit/PrestoDerefPushdownTest.java

unit-presto: unit/PrestoDerefPushdownTest.class
	@echo ""
	@echo "=== UNIT presto-0001/0004: PushDownDereferences/PayloadJoin (ImmutableList→ImmutableSet) ==="
	$(JAVA) -ea -cp . unit.PrestoDerefPushdownTest

# ── webpack unit tests (webpack-0001/0002/0003) ───────────────────────────────

unit/WebpackHmrTest.class: ../defects/webpack/unit/WebpackHmrTest.java
	$(JAVAC) -cp . -d . ../defects/webpack/unit/WebpackHmrTest.java

unit-webpack: unit/WebpackHmrTest.class
	@echo ""
	@echo "=== UNIT webpack-0001/0002/0003: HMR BFS/addAllToSet/createRequire (Array→Set) ==="
	$(JAVA) -ea -cp . unit.WebpackHmrTest

# ── ONOS unit test (onos-0001) ────────────────────────────────────────────────

unit/OnosTarjanTest.class: ../defects/onos/unit/OnosTarjanTest.java
	$(JAVAC) -cp . -d . ../defects/onos/unit/OnosTarjanTest.java

unit-onos-0001: unit/OnosTarjanTest.class
	@echo ""
	@echo "=== UNIT onos-0001: TarjanGraphSearch visited ArrayList→HashSet (101.7x at V=200/E=800) ==="
	$(JAVA) -ea -cp . unit.OnosTarjanTest

# ── BIRD unit tests (bird-0001/0002) ──────────────────────────────────────────

unit/BirdRoutingTest.class: ../defects/bird/unit/BirdRoutingTest.java
	$(JAVAC) -cp . -d . ../defects/bird/unit/BirdRoutingTest.java

unit-bird: unit/BirdRoutingTest.class
	@echo ""
	@echo "=== UNIT bird-0001/0002: OSPF Dijkstra heap (49.2x) + BGP community bsearch (13.1x) ==="
	$(JAVA) -ea -cp . unit.BirdRoutingTest

# ── Bazel unit tests (bazel-0001/0002) ────────────────────────────────────────

unit/BazelAspectCollectionTest.class: ../defects/bazel/unit/BazelAspectCollectionTest.java
	$(JAVAC) -cp . -d . ../defects/bazel/unit/BazelAspectCollectionTest.java

unit-bazel: unit/BazelAspectCollectionTest.class
	@echo ""
	@echo "=== UNIT bazel-0001/0002: AspectCollection seenAspects/create (50x / 13x at n=50) ==="
	$(JAVA) -ea -cp . unit.BazelAspectCollectionTest

# ── ODL unit test (odl-0001) ──────────────────────────────────────────────────

unit/OdlGroupRegistryTest.class: ../defects/odl/unit/OdlGroupRegistryTest.java
	$(JAVAC) -cp . -d . ../defects/odl/unit/OdlGroupRegistryTest.java

unit-odl-0001: unit/OdlGroupRegistryTest.class
	@echo ""
	@echo "=== UNIT odl-0001: DevicesGroupRegistry ArrayList→HashSet (40,000x at G=N=200) ==="
	$(JAVA) -ea -cp . unit.OdlGroupRegistryTest

# ── httpd unit test (httpd-0001) ──────────────────────────────────────────────

unit/HttpdProxyBalancerTest.class: ../defects/httpd/unit/HttpdProxyBalancerTest.java
	$(JAVAC) -cp . -d . ../defects/httpd/unit/HttpdProxyBalancerTest.java

unit-httpd-0001: unit/HttpdProxyBalancerTest.class
	@echo ""
	@echo "=== UNIT httpd-0001: mod_proxy_balancer route apr_hash (50.5x at W=100/R=1000) ==="
	$(JAVA) -ea -cp . unit.HttpdProxyBalancerTest

# ── KiCad unit test (kicad-0001) ──────────────────────────────────────────────

unit/KicadFromToTest.class: ../defects/kicad/unit/KicadFromToTest.java
	$(JAVAC) -cp . -d . ../defects/kicad/unit/KicadFromToTest.java

unit-kicad-0001: unit/KicadFromToTest.class
	@echo ""
	@echo "=== UNIT kicad-0001: from_to_cache BFS vector→unordered_set (34.3x at V=200) ==="
	$(JAVA) -ea -cp . unit.KicadFromToTest

unit/V8RegisterAllocatorTest.class: ../defects/v8/unit/V8RegisterAllocatorTest.java
	$(JAVAC) -cp . -d . ../defects/v8/unit/V8RegisterAllocatorTest.java

unit-v8-0001: unit/V8RegisterAllocatorTest.class
	@echo ""
	@echo "=== UNIT v8-0001: register-allocator spilled_consts ZoneVector→ZoneUnorderedSet (50x at k=50) ==="
	$(JAVA) -ea -cp . unit.V8RegisterAllocatorTest

unit/SpiderMonkeyLinearSumTest.class: ../defects/spidermonkey/unit/SpiderMonkeyLinearSumTest.java
	$(JAVAC) -cp . -d . ../defects/spidermonkey/unit/SpiderMonkeyLinearSumTest.java

unit-spidermonkey-0001: unit/SpiderMonkeyLinearSumTest.class
	@echo ""
	@echo "=== UNIT spidermonkey-0001: LinearSum::add Vector→HashMap Ion bounds-check (O(N*T)→O(N)) ==="
	$(JAVA) -ea -cp . unit.SpiderMonkeyLinearSumTest

unit/LlvmAliasSetTest.class: ../defects/llvm/unit/LlvmAliasSetTest.java
	$(JAVAC) -cp . -d . ../defects/llvm/unit/LlvmAliasSetTest.java

unit-llvm-0002: unit/LlvmAliasSetTest.class
	@echo ""
	@echo "=== UNIT llvm-0002/0003: AliasSet MemoryLocs SmallVector→DenseSet + LCSSA isExitBlock SmallPtrSet ==="
	$(JAVA) -ea -cp . unit.LlvmAliasSetTest

unit/OctaveVecdimTest.class: ../defects/octave/unit/OctaveVecdimTest.java
	$(JAVAC) -cp . -d . ../defects/octave/unit/OctaveVecdimTest.java

unit-octave-0001: unit/OctaveVecdimTest.class
	@echo ""
	@echo "=== UNIT octave-0001: vecdim std::find→std::binary_search on sorted vector ==="
	$(JAVA) -ea -cp . unit.OctaveVecdimTest

unit/RabbitMQQueueTest.class: ../defects/rabbitmq/unit/RabbitMQQueueTest.java
	$(JAVAC) -cp . -d . ../defects/rabbitmq/unit/RabbitMQQueueTest.java

unit-rabbitmq: unit/RabbitMQQueueTest.class
	@echo ""
	@echo "=== UNIT rabbitmq-0001/0002: classic-queue [pid()]→map + sac-coordinator gb_sets (5/5) ==="
	$(JAVA) -ea -cp . unit.RabbitMQQueueTest

unit/CFEngineRlistTest.class: ../defects/cfengine/unit/CFEngineRlistTest.java
	$(JAVAC) -cp . -d . ../defects/cfengine/unit/CFEngineRlistTest.java

unit-cfengine: unit/CFEngineRlistTest.class
	@echo ""
	@echo "=== UNIT cfengine-0001/0002/0003: getindices/unique/maparray Rlist→StringSet ==="
	$(JAVA) -ea -cp . unit.CFEngineRlistTest

unit/TerraformDagTest.class: ../defects/terraform/unit/TerraformDagTest.java
	$(JAVAC) -cp . -d . ../defects/terraform/unit/TerraformDagTest.java

unit-terraform: unit/TerraformDagTest.class
	@echo ""
	@echo "=== UNIT terraform-0001/0002 + saltstack-0001: inStack/EdgesTo/has_loop O(1) fix ==="
	$(JAVA) -ea -cp . unit.TerraformDagTest

unit/AnsibleRoleTest.class: ../defects/ansible/unit/AnsibleRoleTest.java
	$(JAVAC) -cp . -d . ../defects/ansible/unit/AnsibleRoleTest.java

unit-ansible: unit/AnsibleRoleTest.class
	@echo ""
	@echo "=== UNIT ansible-0001/0002 + puppet-0001: seen-list/collections/BFS-path O(1) fix ==="
	$(JAVA) -ea -cp . unit.AnsibleRoleTest

unit/NetworkXCyclesTest.class: ../defects/networkx/unit/NetworkXCyclesTest.java
	$(JAVAC) -cp . -d . ../defects/networkx/unit/NetworkXCyclesTest.java

unit-networkx: unit/NetworkXCyclesTest.class
	@echo ""
	@echo "=== UNIT networkx-0001 + rubocop-0001 + solargraph-0001: list→set O(1) (5/5) ==="
	$(JAVA) -ea -cp . unit.NetworkXCyclesTest

unit/JenkinsDependencyGraphTest.class: ../defects/jenkins/unit/JenkinsDependencyGraphTest.java
	$(JAVAC) -cp . -d . ../defects/jenkins/unit/JenkinsDependencyGraphTest.java

unit-jenkins: unit/JenkinsDependencyGraphTest.class
	@echo ""
	@echo "=== UNIT jenkins-0001/0002: DependencyGraph edge index + ChildJobs HashSet (5/5) ==="
	$(JAVA) -ea -cp . unit.JenkinsDependencyGraphTest

unit/MavenGraphBuilderTest.class: ../defects/maven/unit/MavenGraphBuilderTest.java
	$(JAVAC) -cp . -d . ../defects/maven/unit/MavenGraphBuilderTest.java

unit-maven-extra: unit/MavenGraphBuilderTest.class
	@echo ""
	@echo "=== UNIT maven-0004/0005: sortedProjects/sortedNodes indexOf→HashMap (5/5) ==="
	$(JAVA) -ea -cp . unit.MavenGraphBuilderTest

unit/TinkerPopPathTest.class: ../defects/tinkerpop/unit/TinkerPopPathTest.java
	$(JAVAC) -cp . -d . ../defects/tinkerpop/unit/TinkerPopPathTest.java

unit-tinkerpop-0001: unit/TinkerPopPathTest.class
	@echo ""
	@echo "=== UNIT tinkerpop-0001: Path.isSimple() O(n²)→O(n) HashSet (99.5x at n=200) ==="
	$(JAVA) -ea -cp . unit.TinkerPopPathTest

# ── Integration ───────────────────────────────────────────────────────────────
# Runs against the installed JDK's compiled GraphUtils.
# Proves real timing growth and confirms algorithm correctness.

integration: integration/InferenceGraphScalingTest.class
	@echo ""
	@echo "=== INTEGRATION ==="
	$(JAVA) $(EXPORTS) -cp . integration.InferenceGraphScalingTest

integration/InferenceGraphScalingTest.class: support/AbstractTestNode.java integration/InferenceGraphScalingTest.java
	$(JAVAC) $(EXPORTS) -cp . support/AbstractTestNode.java integration/InferenceGraphScalingTest.java

# ── Functional ────────────────────────────────────────────────────────────────
# Generates Java source and compiles it with the system javac.
# Measures compilation latency across increasing generic chain depths.

functional: functional/CompilerBenchmarkTest.class
	@echo ""
	@echo "=== FUNCTIONAL ==="
	$(JAVA) -cp . functional.CompilerBenchmarkTest

functional/CompilerBenchmarkTest.class: functional/CompilerBenchmarkTest.java
	$(JAVAC) -cp . functional/CompilerBenchmarkTest.java

# ── Bench ─────────────────────────────────────────────────────────────────────
# bench       — before/after for 0001 only (original single-defect benchmark)
# bench-all   — before/after for all five defects (consolidated table)
# bench-real  — patches GraphUtils.java, runs InferenceGraphScalingTest before+after

bench: bench/BeforeAfterBenchmark.class
	@echo ""
	@echo "=== BEFORE/AFTER BENCHMARK (0001) ==="
	$(JAVA) -cp . bench.BeforeAfterBenchmark

bench/BeforeAfterBenchmark.class: support/TarjanAlgorithm.java bench/BeforeAfterBenchmark.java
	$(JAVAC) -cp . support/TarjanAlgorithm.java bench/BeforeAfterBenchmark.java

bench-all: bench/AllDefectsBenchmark.class
	@echo ""
	@echo "=== BEFORE/AFTER BENCHMARK (ALL DEFECTS) ==="
	$(JAVA) -cp . bench.AllDefectsBenchmark

UNIT_FOR_BENCH := ../defects/hive/unit/HiveGenMRSeenOpsTest.java \
                  ../defects/spark/unit/SparkAnalyzerWindowAggTest.java \
                  ../defects/frrouting/unit/FrroutingOspfVertexParentTest.java \
                  ../defects/tor/unit/TorRouterlistTest.java \
                  ../defects/solc/unit/SolcCallGraphCycleTest.java \
                  ../defects/solc/unit/SolcAssemblyRjumpTest.java \
                  ../defects/buildkit/unit/BuildkitHasLinkTest.java \
                  ../defects/kafka/unit/KafkaStickyAssignorTest.java \
                  ../defects/spring/unit/SpringBeanFactoryTest.java \
                  ../defects/presto/unit/PrestoDerefPushdownTest.java \
                  ../defects/webpack/unit/WebpackHmrTest.java

bench/AllDefectsBenchmark.class: $(SUPPORT_ALL) $(UNIT_FOR_BENCH) bench/AllDefectsBenchmark.java
	$(JAVAC) -cp . -d . $(SUPPORT_ALL) $(UNIT_FOR_BENCH) bench/AllDefectsBenchmark.java

bench-real:
	@echo ""
	@echo "=== BEFORE/AFTER: REAL JDK (all patched) ==="
	bash bench/benchmark-real.sh

# ── Minecraft / Gumyum benchmarks ─────────────────────────────────────────────
# Require JDK 25 + guava on classpath (Minecraft class file version 69).
# Set JAVA25=/path/to/java and GUAVA=/path/to/guava.jar if not at defaults.

bench/DependencySorterBenchmark.class: bench/DependencySorterBenchmark.java
	$(JAVAC25) --release 21 -cp $(GUAVA) bench/DependencySorterBenchmark.java -d bench/

# minecraft-0001: DependencySorter diamond-depth scaling (depths 2–16)
bench-mc-server: bench/DependencySorterBenchmark.class
	@echo ""
	@echo "=== minecraft-0001: DependencySorter depth 2–16 ==="
	$(JAVA25) -cp bench:$(GUAVA) bench.DependencySorterBenchmark

bench/BenchMax.class: bench/BenchMax.java
	$(JAVAC25) --release 21 -cp $(GUAVA) bench/BenchMax.java -d bench/

# Extreme-scale: javac Tarjan V→3200, MC diamond D→18, Create BFS V→5000
bench-max: bench/BenchMax.class
	@echo ""
	@echo "=== BenchMax — extreme-scale all ecosystems ==="
	$(JAVA25) -cp bench:$(GUAVA) bench.BenchMax

# All Minecraft + Create benchmarks
bench-gumyum: bench-mc-server bench-max
	@echo ""
	@echo "=== Gumyum benchmarks complete ==="

# Everything: javac (all 5 defects) + Minecraft + BenchMax
bench-everything: bench-all bench-mc-server bench-max
	@echo ""
	@echo "=== All benchmarks complete ==="

# ── Load simulation: concurrent players, world load, TPS ──────────────────────
# Simulates N concurrent player joins + game-loop ticks before/after patch.
# Requires Guava. No server needed.

bench/LoadSimBenchmark.class: bench/LoadSimBenchmark.java
	$(JAVAC25) --release 21 -cp $(GUAVA) bench/LoadSimBenchmark.java -d .

bench-loadsim: bench/LoadSimBenchmark.class
	@echo ""
	@echo "=== LoadSim — concurrent players, world load, TPS ==="
	$(JAVA25) -cp .:$(GUAVA) bench.LoadSimBenchmark

# ── Elytra stress benchmark — final benchmark ────────────────────────────────
# 30 players, Y=200, all directions, firework boost every 3 s.
# Exercises: DependencySorter isCyclic (world load) + entity tracking (flight).
# Three tiers: unpatched / mitigated / enriched.

bench/WalkeruinElytraStressBenchmark.class: bench/WalkeruinElytraStressBenchmark.java
	$(JAVAC25) --release 21 -cp $(GUAVA) bench/WalkeruinElytraStressBenchmark.java -d bench/

bench-elytra: bench/WalkeruinElytraStressBenchmark.class
	@echo ""
	@echo "=== walkeruin ElytraStressBenchmark — 30 players, fireworks, all directions ==="
	$(JAVA25) -cp bench:$(GUAVA) bench.WalkeruinElytraStressBenchmark

# ── Three-tier server benchmarks ──────────────────────────────────────────────
# Three tiers for the enriched-minecraft paper:
#   unpatched   control: vanilla jar, depth-16 (defect present)
#   mitigated   fix only: patched jar, depth-16 (same game, fast)
#   enriched    new territory: patched jar, depth-24 / 300 NS (impossible before)
#
# --play variants keep the server up for human play testing.
# Requires: /home/fox/Downloads/server.jar (vanilla)
#           /tmp/mc-bench/server-patched.jar (visited-set fix applied)
#           /tmp/jdk25/bin/java
#           node (mineflayer raw-connect.mjs)

MC_BENCH := ../tools/mc-bench/bench-server.sh

bench-unpatched:
	@echo ""
	@echo "=== BENCH: unpatched (control) ==="
	bash $(MC_BENCH) unpatched 20

bench-mitigated:
	@echo ""
	@echo "=== BENCH: mitigated (fix applied) ==="
	bash $(MC_BENCH) mitigated 20

bench-enriched:
	@echo ""
	@echo "=== BENCH: enriched (new territory, D=48 / 1000 NS / 32 xrefs) ==="
	bash $(MC_BENCH) enriched 20

# Run all three tiers sequentially — produces comparable results.json in each dir.
bench-three-tier: bench-unpatched bench-mitigated bench-enriched
	@echo ""
	@echo "=== Three-tier benchmark complete ==="
	@echo "Results:"
	@for d in unpatched mitigated enriched; do \
	    f=/tmp/mc-bench/$$d/results.txt; \
	    [ -f "$$f" ] && echo "  $$d: $$(cat $$f | tr '\n' '  ')" || echo "  $$d: (not run)"; \
	done

# Human play-test mode: server stays up, prints connection info, waits for Ctrl-C.
play-unpatched:
	@echo ""
	@echo "=== PLAY TEST: unpatched — connect to localhost:25565 ==="
	bash $(MC_BENCH) unpatched 20 --play

play-mitigated:
	@echo ""
	@echo "=== PLAY TEST: mitigated — connect to localhost:25566 ==="
	bash $(MC_BENCH) mitigated 20 --play

play-enriched:
	@echo ""
	@echo "=== PLAY TEST: enriched — connect to localhost:25567 ==="
	bash $(MC_BENCH) enriched 20 --play

# ── Workbench — Sym² manifold workbench (Java port of unworkbench.com) ────────
# Compile with patched javac, launch Swing UI.
#
#   make workbench          — compile + launch (no --patch-module; shows UNPATCHED)
#   make workbench-build    — compile only
#   make workbench-patched  — build patch classes, launch with --patch-module
#   make workbench-verify   — print patch status without launching UI

WORKBENCH_SRC := workbench/Manifold.java workbench/Friend.java \
                 workbench/PatchVerifier.java workbench/Workbench.java

PATCH_OUT     := /tmp/jt-all-classes
REPO_ROOT     := $(shell cd .. && pwd)
PATCH_FLAG    := --patch-module jdk.compiler=$(PATCH_OUT)
WB_EXPORTS    := --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

workbench/Workbench.class: $(WORKBENCH_SRC)
	$(JAVAC) $(WB_EXPORTS) -cp . $(WORKBENCH_SRC)

workbench-build: workbench/Workbench.class
	@echo "Workbench compiled."

workbench: workbench/Workbench.class
	@echo ""
	@echo "=== SYM2 MANIFOLD WORKBENCH (unpatched) ==="
	$(JAVA) $(WB_EXPORTS) -cp . workbench.Workbench

# Build patched jdk.compiler classes (0001 + 0004 + 0005), then launch.
# Mirrors benchmark-real.sh — reuses existing build if present.
$(PATCH_OUT)/com/sun/tools/javac/util/GraphUtils.class:
	@echo "[patch] Compiling patched javac classes → $(PATCH_OUT)"
	@SRC_UTIL=$(REPO_ROOT)/src/jdk.compiler/share/classes/com/sun/tools/javac/util; \
	 SRC_COMP=$(REPO_ROOT)/src/jdk.compiler/share/classes/com/sun/tools/javac/comp; \
	 rm -rf /tmp/jt-all-src /tmp/jt-ctx-src $(PATCH_OUT); \
	 mkdir -p /tmp/jt-all-src/com/sun/tools/javac/util; \
	 mkdir -p /tmp/jt-all-src/com/sun/tools/javac/comp; \
	 mkdir -p /tmp/jt-ctx-src/com/sun/tools/javac/comp; \
	 mkdir -p $(PATCH_OUT); \
	 cp $$SRC_UTIL/GraphUtils.java   /tmp/jt-all-src/com/sun/tools/javac/util/; \
	 cp $$SRC_UTIL/Dependencies.java /tmp/jt-all-src/com/sun/tools/javac/util/; \
	 cp $$SRC_COMP/InferenceContext.java /tmp/jt-ctx-src/com/sun/tools/javac/comp/; \
	 $(JAVAC) --patch-module "jdk.compiler=/tmp/jt-all-src" -d $(PATCH_OUT) \
	     /tmp/jt-all-src/com/sun/tools/javac/util/GraphUtils.java \
	     /tmp/jt-all-src/com/sun/tools/javac/util/Dependencies.java; \
	 $(JAVAC) --patch-module "jdk.compiler=/tmp/jt-ctx-src" -d $(PATCH_OUT) \
	     /tmp/jt-ctx-src/com/sun/tools/javac/comp/InferenceContext.java
	@echo "[patch] Done."

workbench-patched: workbench/Workbench.class $(PATCH_OUT)/com/sun/tools/javac/util/GraphUtils.class
	@echo ""
	@echo "=== SYM2 MANIFOLD WORKBENCH (patched: 0001+0004+0005) ==="
	$(JAVA) $(PATCH_FLAG) $(WB_EXPORTS) -cp . workbench.Workbench

workbench-verify: workbench/Workbench.class
	@echo ""
	@echo "=== PATCH VERIFY (unpatched runtime) ==="
	@$(JAVA) $(WB_EXPORTS) -cp . workbench.PatchVerifier; \
	 if [ $$? -eq 0 ]; then echo "STATUS: PATCHED"; else echo "STATUS: UNPATCHED"; fi
	@echo ""
	@echo "=== PATCH VERIFY (with --patch-module) ==="
	@$(MAKE) $(PATCH_OUT)/com/sun/tools/javac/util/GraphUtils.class
	@$(JAVA) $(PATCH_FLAG) $(WB_EXPORTS) -cp . workbench.PatchVerifier; \
	 if [ $$? -eq 0 ]; then echo "STATUS: PATCHED"; else echo "STATUS: UNPATCHED"; fi

# ── Clean ─────────────────────────────────────────────────────────────────────

clean:
	find . -name "*.class" -delete
	@echo "Cleaned."
