package com.lingniu.ingest.protocol.gb32960.model;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * 完整解析后的 32960 消息。一条消息要么是实时/补发上报（携带 {@link InfoBlock} 列表），
 * 要么是登入/登出/平台/心跳/校时/激活/密钥交换等命令（携带 {@link CommandBody}），
 * 二者互斥。
 *
 * @param header      报文头
 * @param infoBlocks  实时/补发上报的信息体列表；其他命令为空列表
 * @param commandBody 非实时上报的命令数据单元；实时/补发上报为 null
 * @param signature   实时上报尾部的签名原始字节（2025 版新增，2016 版为 null）
 */
public record Gb32960Message(
        Gb32960Header header,
        List<InfoBlock> infoBlocks,
        CommandBody commandBody,
        byte[] signature
) {

    /** 便捷构造：只含信息体（实时/补发上报，2016 版常用）。 */
    public Gb32960Message(Gb32960Header header, List<InfoBlock> infoBlocks) {
        this(header, infoBlocks == null ? Collections.emptyList() : infoBlocks, null, null);
    }

    /** 便捷构造：非实时命令。 */
    public Gb32960Message(Gb32960Header header, CommandBody commandBody) {
        this(header, Collections.emptyList(), commandBody, null);
    }

    public boolean isReport() {
        return header.command() == CommandType.REALTIME_REPORT
                || header.command() == CommandType.RESEND_REPORT;
    }

    @SuppressWarnings("unchecked")
    public <T extends InfoBlock> Optional<T> findBlock(Class<T> type) {
        return (Optional<T>) infoBlocks.stream().filter(type::isInstance).findFirst();
    }
}
