package org.raddatz.familienarchiv.document;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;

import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Asserts the Java title label against the SAME shared fixture table the TS
 * formatter spec uses ({@code docs/date-label-fixtures.json}). This is the
 * drift guard requested in #666 review: the two label implementations cannot
 * silently diverge (en-dash vs hyphen, "ca." vs "circa", season words, range
 * collapse) because both are pinned to one committed rule set.
 */
class DocumentTitleFormatterTest {

    @TestFactory
    List<DynamicTest> matchesSharedFixtureTable() throws Exception {
        // Maven runs tests from the backend/ module dir; the fixture lives at repo-root docs/.
        Path fixture = Path.of("..", "docs", "date-label-fixtures.json");
        JsonNode root = new ObjectMapper().readTree(Files.readString(fixture));
        List<DynamicTest> tests = new ArrayList<>();
        for (JsonNode c : root.get("cases")) {
            String name = c.get("name").asText();
            LocalDate anchor = parseDate(c.get("anchor"));
            DatePrecision precision = DatePrecision.valueOf(c.get("precision").asText());
            LocalDate end = parseDate(c.get("end"));
            String raw = c.get("raw").isNull() ? null : c.get("raw").asText();
            String expected = c.get("expected").asText();
            tests.add(DynamicTest.dynamicTest(name, () ->
                    assertThat(DocumentTitleFormatter.formatTitleDate(anchor, precision, end, raw))
                            .isEqualTo(expected)));
        }
        return tests;
    }

    private static LocalDate parseDate(JsonNode node) {
        return node == null || node.isNull() ? null : LocalDate.parse(node.asText());
    }
}
