package p.studio.compiler.specs;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

class BackendClaimScopeSpecTest {
    private static final String LOWERING_SPEC_RELATIVE_PATH =
            "docs/specs/compiler/20. IRBackend to IRVM Lowering Specification.md";
    private static final String MATRIX_RELATIVE_PATH =
            "docs/specs/compiler/22. Backend Spec-to-Test Conformance Matrix.md";

    @Test
    void loweringSpecMustDeclareSpawnYieldOutsideCoreV1ClaimScope() throws IOException {
        final var content = Files.readString(locateRepoRoot().resolve(LOWERING_SPEC_RELATIVE_PATH));

        assertTrue(content.contains("`SPAWN` and `YIELD` are outside the executable `core-v1` claim scope"),
                "lowering spec must declare SPAWN/YIELD as out-of-scope for core-v1 claim");
    }

    @Test
    void matrixMustMarkSpawnYieldRowsAsClaimRescoped() throws IOException {
        final var lines = Files.readAllLines(locateRepoRoot().resolve(MATRIX_RELATIVE_PATH));
        final var spawnRow = findRequirementRow(lines, "G20-9.4.2")
                .orElseThrow(() -> new AssertionError("missing matrix row for requirement: G20-9.4.2"));
        final var yieldRow = findRequirementRow(lines, "G20-9.4.3")
                .orElseThrow(() -> new AssertionError("missing matrix row for requirement: G20-9.4.3"));

        assertTrue(spawnRow.contains("| pass |"), "G20-9.4.2 row must not remain deferred");
        assertTrue(yieldRow.contains("| pass |"), "G20-9.4.3 row must not remain deferred");
        assertTrue(spawnRow.contains("out of scope for core-v1 claim"),
                "G20-9.4.2 row must include explicit claim rescope note");
        assertTrue(yieldRow.contains("out of scope for core-v1 claim"),
                "G20-9.4.3 row must include explicit claim rescope note");
    }

    private Optional<String> findRequirementRow(
            final List<String> lines,
            final String requirementId) {
        final var prefix = "| " + requirementId + " |";
        return lines.stream().filter(line -> line.startsWith(prefix)).findFirst();
    }

    private Path locateRepoRoot() {
        var cursor = Path.of(System.getProperty("user.dir")).toAbsolutePath().normalize();
        while (cursor != null) {
            final var hasDocs = Files.isDirectory(cursor.resolve("docs/specs/compiler"));
            final var hasCompiler = Files.isDirectory(cursor.resolve("prometeu-compiler"));
            if (hasDocs && hasCompiler) {
                return cursor;
            }
            cursor = cursor.getParent();
        }
        fail("could not locate repository root from working directory");
        throw new IllegalStateException("unreachable");
    }
}
