package com.lingniu.ingest.sink.kafka;

import com.lingniu.ingest.api.ProtocolId;
import com.lingniu.ingest.api.event.RawArchiveKeys;
import com.lingniu.ingest.api.event.RealtimePayload;
import com.lingniu.ingest.api.event.VehicleEvent;
import com.lingniu.ingest.sink.kafka.proto.VehicleEnvelope;
import org.junit.jupiter.api.Test;

import java.time.Instant;
import java.util.Map;

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

class EnvelopeMapperTelemetrySnapshotTest {

    @Test
    void mapsVehicleEventToFullFieldTelemetrySnapshot() {
        VehicleEvent.Realtime event = new VehicleEvent.Realtime(
                "event-1",
                "VIN001",
                ProtocolId.GB32960,
                Instant.parse("2026-06-22T08:00:00Z"),
                Instant.parse("2026-06-22T08:00:01Z"),
                "trace-1",
                Map.of("protocolVersion", "V2016", "rawArchiveUri", "archive://raw/event-1.bin"),
                new RealtimePayload(
                        80.5,
                        12345.6,
                        55.0,
                        610.0,
                        -20.5,
                        null,
                        null,
                        null,
                        8.2,
                        35.0,
                        null,
                        RealtimePayload.VehicleState.STARTED,
                        RealtimePayload.ChargingState.UNCHARGED,
                        RealtimePayload.RunningMode.FUEL,
                        3,
                        null,
                        null,
                        113.12,
                        23.45,
                        null,
                        null,
                        null,
                        null
                )
        );

        VehicleEnvelope envelope = new EnvelopeMapper("node-1").toEnvelope(event);

        assertThat(envelope.getTelemetrySnapshot().getEventType()).isEqualTo("REALTIME");
        assertThat(envelope.getTelemetrySnapshot().getRawArchiveUri()).isEqualTo("archive://raw/event-1.bin");
        assertThat(envelope.getTelemetrySnapshot().getFieldsList())
                .anySatisfy(field -> {
                    assertThat(field.getKey()).isEqualTo("total_mileage_km");
                    assertThat(field.getValueType()).isEqualTo("DOUBLE");
                    assertThat(field.getValue()).isEqualTo("12345.6");
                    assertThat(field.getUnit()).isEqualTo("km");
                })
                .anySatisfy(field -> {
                    assertThat(field.getKey()).isEqualTo("hydrogen_high_pressure_mpa");
                    assertThat(field.getValue()).isEqualTo("35.0");
                    assertThat(field.getUnit()).isEqualTo("MPa");
                });
    }

    @Test
    void rawArchiveEnvelopeCarriesLogicalArchiveUri() {
        VehicleEvent.RawArchive raw = new VehicleEvent.RawArchive(
                "raw-808-1",
                "VIN-JT808-001",
                ProtocolId.JT808,
                Instant.parse("2026-06-22T08:00:00Z"),
                Instant.parse("2026-06-22T08:00:01Z"),
                "trace-raw-1",
                Map.of(),
                0x0200,
                0,
                new byte[]{0x7e, 0x02, 0x00, 0x7e});

        VehicleEnvelope envelope = new EnvelopeMapper("node-1").toEnvelope(raw);

        String key = RawArchiveKeys.key(raw);
        assertThat(envelope.hasRawArchive()).isTrue();
        assertThat(envelope.getRawArchive().getUri()).isEqualTo(RawArchiveKeys.logicalUri(key));
        assertThat(envelope.getRawArchive().getSizeBytes()).isEqualTo(4);
        assertThat(envelope.getMetadataMap()).containsEntry(RawArchiveKeys.META_URI, RawArchiveKeys.logicalUri(key));
        assertThat(envelope.hasRawFrameFact()).isTrue();
        assertThat(envelope.getRawFrameFact().getFrameId()).startsWith("rf_");
        assertThat(envelope.getRawFrameFact().getVehicleKey()).isEqualTo("VIN-JT808-001");
        assertThat(envelope.getRawFrameFact().getVin()).isEqualTo("VIN-JT808-001");
        assertThat(envelope.getRawFrameFact().getMessageId()).isEqualTo(0x0200);
        assertThat(envelope.getRawFrameFact().getRawUri()).isEqualTo(RawArchiveKeys.logicalUri(key));
        assertThat(envelope.getRawFrameFact().getRawSizeBytes()).isEqualTo(4);
        assertThat(envelope.getRawFrameFact().getChecksum()).startsWith("sha256:");
    }
}
