package com.lingniu.ingest.facts;

import com.lingniu.ingest.api.ProtocolId;

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

public record RawFrameFact(
        String frameId,
        ProtocolId protocol,
        String vehicleKey,
        String vin,
        String phone,
        int messageId,
        int subType,
        Instant eventTime,
        Instant receivedAt,
        String peer,
        String rawUri,
        String checksum,
        long rawSizeBytes,
        ParseStatus parseStatus,
        String parseError,
        Map<String, String> metadata
) {
    public RawFrameFact {
        frameId = required(frameId, "frameId");
        if (protocol == null) {
            throw new IllegalArgumentException("protocol must not be null");
        }
        vehicleKey = required(vehicleKey, "vehicleKey");
        receivedAt = required(receivedAt, "receivedAt");
        eventTime = eventTime == null ? receivedAt : eventTime;
        rawUri = required(rawUri, "rawUri");
        checksum = required(checksum, "checksum");
        if (rawSizeBytes < 0) {
            throw new IllegalArgumentException("rawSizeBytes must not be negative");
        }
        parseStatus = parseStatus == null ? ParseStatus.NOT_PARSED : parseStatus;
        vin = clean(vin);
        phone = clean(phone);
        peer = clean(peer);
        parseError = clean(parseError);
        metadata = metadata == null ? Map.of() : Map.copyOf(metadata);
    }

    private static String required(String value, String field) {
        String cleaned = clean(value);
        if (cleaned.isBlank()) {
            throw new IllegalArgumentException(field + " must not be blank");
        }
        return cleaned;
    }

    private static Instant required(Instant value, String field) {
        if (value == null) {
            throw new IllegalArgumentException(field + " must not be null");
        }
        return value;
    }

    private static String clean(String value) {
        return value == null ? "" : value.trim();
    }
}
