package com.lingniu.ingest.protocol.jt1078;

import com.lingniu.ingest.api.event.VehicleEvent;
import com.lingniu.ingest.identity.InMemoryVehicleIdentityService;
import com.lingniu.ingest.protocol.jt1078.model.Jt1078MessageId;
import com.lingniu.ingest.protocol.jt808.mapper.Jt808EventMapper;
import com.lingniu.ingest.protocol.jt808.model.Jt808Body;
import com.lingniu.ingest.protocol.jt808.model.Jt808Header;
import com.lingniu.ingest.protocol.jt808.model.Jt808Message;
import org.junit.jupiter.api.Test;

import java.util.List;

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

class Jt1078EventMappingTest {

    private final Jt808EventMapper mapper = new Jt808EventMapper(new InMemoryVehicleIdentityService());
    private final Jt808Header header = new Jt808Header(
            0x1003, 0, 0, false, Jt808Header.ProtocolVersion.V2013, "13800138000", 1, 0, 0);

    @Test
    void mediaAttributesProduceQueryableMediaMetaEvent() {
        Jt808Body.MediaAttributes attrs = new Jt808Body.MediaAttributes(1, 2, 3, 4, 320, true, 98, 4, 8, new byte[]{1, 2});

        List<VehicleEvent> events = mapper.toEvents(new Jt808Message(header, attrs));

        assertThat(events).hasSize(1);
        assertThat(events.getFirst()).isInstanceOf(VehicleEvent.MediaMeta.class);
        VehicleEvent.MediaMeta event = (VehicleEvent.MediaMeta) events.getFirst();
        assertThat(event.mediaType()).contains("videoEncoding=98");
        assertThat(event.metadata()).containsEntry("jt1078Message", "mediaAttributes");
    }

    @Test
    void fileUploadCompleteProducesPassthroughEventWithResultMetadata() {
        Jt808Body.FileUploadComplete done = new Jt808Body.FileUploadComplete(0x1234, 0, new byte[]{0x12, 0x34, 0});

        List<VehicleEvent> events = mapper.toEvents(new Jt808Message(header, done));

        assertThat(events).hasSize(1);
        assertThat(events.getFirst()).isInstanceOf(VehicleEvent.Passthrough.class);
        VehicleEvent.Passthrough event = (VehicleEvent.Passthrough) events.getFirst();
        assertThat(event.metadata()).containsEntry("jt1078Message", "fileUploadComplete");
        assertThat(event.metadata()).containsEntry("uploadResult", "0");
    }

    @Test
    void fileListProducesPassthroughEventWithQueryableSummaryMetadata() {
        Jt808Header fileListHeader = new Jt808Header(
                Jt1078MessageId.TERMINAL_FILE_LIST, 0, 0, false,
                Jt808Header.ProtocolVersion.V2013, "13800138000", 1, 0, 0);
        byte[] raw = new byte[]{0x12, 0x34, 0, 0, 0, 2};
        Jt808Body.FileList fileList = new Jt808Body.FileList(0x1234, 2, raw);

        List<VehicleEvent> events = mapper.toEvents(new Jt808Message(fileListHeader, fileList));

        assertThat(events).hasSize(1);
        assertThat(events.getFirst()).isInstanceOf(VehicleEvent.Passthrough.class);
        VehicleEvent.Passthrough event = (VehicleEvent.Passthrough) events.getFirst();
        assertThat(event.passthroughType()).isEqualTo(Jt1078MessageId.TERMINAL_FILE_LIST);
        assertThat(event.data()).containsExactly(raw);
        assertThat(event.metadata())
                .containsEntry("jt1078Message", "fileList")
                .containsEntry("responseSerialNo", "4660")
                .containsEntry("fileCount", "2");
    }

    @Test
    void passengerVolumeProducesPassthroughEventWithQueryableMetadata() {
        Jt808Header passengerHeader = new Jt808Header(
                Jt1078MessageId.TERMINAL_PASSENGER_VOLUME, 0, 0, false,
                Jt808Header.ProtocolVersion.V2013, "13800138000", 1, 0, 0);
        byte[] raw = new byte[]{1, 2, 3};
        Jt808Body.PassengerVolume passengerVolume = new Jt808Body.PassengerVolume(
                2, "2026-06-22T15:30:00", "2026-06-22T16:00:00", 21, 3, raw);

        List<VehicleEvent> events = mapper.toEvents(new Jt808Message(passengerHeader, passengerVolume));

        assertThat(events).hasSize(1);
        assertThat(events.getFirst()).isInstanceOf(VehicleEvent.Passthrough.class);
        VehicleEvent.Passthrough event = (VehicleEvent.Passthrough) events.getFirst();
        assertThat(event.passthroughType()).isEqualTo(Jt1078MessageId.TERMINAL_PASSENGER_VOLUME);
        assertThat(event.data()).containsExactly(raw);
        assertThat(event.metadata())
                .containsEntry("jt1078Message", "passengerVolume")
                .containsEntry("channelId", "2")
                .containsEntry("startTime", "2026-06-22T15:30:00")
                .containsEntry("endTime", "2026-06-22T16:00:00")
                .containsEntry("passengerGetOn", "21")
                .containsEntry("passengerGetOff", "3");
    }
}
