package at.procon.eventhub.tachographfilesession.service;

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

import at.procon.eventhub.tachographfilesession.model.DriverExtractionSession;
import at.procon.eventhub.tachographfilesession.model.TachographFileSession;
import at.procon.eventhub.tachographfilesession.model.TachographFileSessionMetadata;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Test;

class DriverCardXmlExtractionServiceTest {

    private final TachographXmlParser parser = new TachographXmlParser();
    private final DriverCardXmlExtractionService service = new DriverCardXmlExtractionService(
            new DriverKeyFactory(),
            new VehicleKeyFactory()
    );

    @Test
    void extractsDriverCardVehiclesAndActivities() {
        TachographFileSession session = service.extract(
                parser.parse(DriverCardXmlSamples.validDriverCardXml()),
                new TachographFileSessionMetadata(
                        "default",
                        "legalrequirements-drivercard",
                        "sample",
                        "sample.ddd",
                        "abc",
                        10,
                        "42",
                        "def",
                        true,
                        null
                ),
                Instant.now(),
                Instant.now().plus(4, ChronoUnit.HOURS)
        );

        assertThat(session.driversByKey()).hasSize(1);
        DriverExtractionSession driver = session.driversByKey().values().iterator().next();
        assertThat(driver.driverKey()).isEqualTo("12:12345678901200");
        assertThat(driver.driver().surname()).isEqualTo("Muster");
        assertThat(driver.driverCard().sourceDriverCardId()).isEqualTo("CARD:12:12345678901200");
        assertThat(driver.vehicleRegistrations()).hasSize(2);
        assertThat(driver.vehicles()).hasSize(2);
        assertThat(driver.cardVehicleUsageIntervals()).hasSize(2);
        assertThat(driver.cardActivityIntervals()).hasSize(3);
        assertThat(driver.cardActivityIntervals().get(0).registrationKey()).isEqualTo("12:W-12345A");
        assertThat(driver.cardActivityIntervals().get(1).to()).isEqualTo(driver.cardVehicleUsageIntervals().get(0).to().plusSeconds(1));
        assertThat(driver.cardActivityIntervals().get(2).registrationKey()).isEqualTo("12:W-54321B");
    }

    @Test
    void extractsActivitiesWhenTimeOfChangeHasNoOffset() {
        TachographFileSession session = service.extract(
                parser.parse(DriverCardXmlSamples.validDriverCardXmlWithLocalActivityTimes()),
                new TachographFileSessionMetadata(
                        "default",
                        "legalrequirements-drivercard",
                        "sample",
                        "sample.ddd",
                        "abc",
                        10,
                        "42",
                        "def",
                        true,
                        null
                ),
                Instant.now(),
                Instant.now().plus(4, ChronoUnit.HOURS)
        );

        DriverExtractionSession driver = session.driversByKey().values().iterator().next();
        assertThat(driver.cardActivityIntervals()).hasSize(3);
        assertThat(driver.cardActivityIntervals())
                .extracting(interval -> interval.from().toString())
                .contains("2026-04-01T08:00Z", "2026-04-01T12:00Z");
    }

    @Test
    void keepsLastOpenVehicleUseRecordWithoutSynthesizingActivityTail() {
        TachographFileSession session = service.extract(
                parser.parse(DriverCardXmlSamples.driverCardXmlWithOpenVehicleUseRecord()),
                new TachographFileSessionMetadata(
                        "default",
                        "legalrequirements-drivercard",
                        "sample",
                        "sample.ddd",
                        "abc",
                        10,
                        "42",
                        "def",
                        true,
                        null
                ),
                Instant.now(),
                Instant.now().plus(4, ChronoUnit.HOURS)
        );

        DriverExtractionSession driver = session.driversByKey().values().iterator().next();
        assertThat(driver.cardVehicleUsageIntervals()).hasSize(2);
        assertThat(driver.cardVehicleUsageIntervals().get(1).to()).isNull();
        assertThat(driver.cardActivityIntervals()).hasSize(3);
        assertThat(driver.cardActivityIntervals().get(2).registrationKey()).isEqualTo("12:W-54321B");
    }
}
