package com.lingniu.ingest.protocol.gb32960.codec.parser.v2016;

import com.lingniu.ingest.protocol.gb32960.codec.InfoBlockParser;
import com.lingniu.ingest.protocol.gb32960.codec.ValueDecoder;
import com.lingniu.ingest.protocol.gb32960.model.InfoBlock;
import com.lingniu.ingest.protocol.gb32960.model.ProtocolVersion;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * 燃料电池数据 (0x03) —— GB/T 32960.3-2016 表 B.13。变长。
 * fcVoltageV(2) + fcCurrentA(2) + hydrogenConsumption(2,0.01 kg/100km)
 * + probeCount N(2) + probes[N](1B,-40 offset) + 后续氢系统 10 字节固定段。
 */
public final class FuelCellV2016BlockParser implements InfoBlockParser {

    @Override public ProtocolVersion version() { return ProtocolVersion.V2016; }
    @Override public int typeCode() { return 0x03; }
    @Override public int fixedLength() { return -1; }

    @Override
    public InfoBlock parse(ByteBuffer buf) {
        Double fcVoltage = ValueDecoder.scaledU16(buf, 0.1);
        Double fcCurrent = ValueDecoder.scaledU16(buf, 0.1);
        Double consumption = ValueDecoder.scaledU16(buf, 0.01);
        int probeCount = ValueDecoder.u16raw(buf);

        // 防御：probeCount 异常时回退为空列表避免吞 buffer
        List<Integer> probes = new ArrayList<>();
        int tailFixed = 2 + 1 + 2 + 1 + 2 + 1 + 1; // 尾部固定 10 字节
        // probeCount 来自车端报文，错误值会导致尾部固定段错位；这里先确保尾部还能完整解析。
        if (probeCount >= 0 && probeCount <= buf.remaining() - tailFixed) {
            for (int i = 0; i < probeCount; i++) {
                Integer t = ValueDecoder.tempOffset40(buf);
                if (t != null) probes.add(t);
            }
        }
        Double maxHydrogenTempC = ValueDecoder.scaledU16WithOffset(buf, 0.1, -40.0);
        Integer maxHydrogenTempProbeId = ValueDecoder.u8(buf);
        Double maxHydrogenConcentration = ValueDecoder.scaledU16(buf, 0.000001);
        Integer maxHydrogenConcentrationProbeId = ValueDecoder.u8(buf);
        Double maxHydrogenPressure = ValueDecoder.scaledU16(buf, 0.1);
        Integer maxHydrogenPressureProbeId = ValueDecoder.u8(buf);
        Integer hvDcDcStatus = ValueDecoder.u8(buf);

        return new InfoBlock.Gb32960V2016.FuelCell(
                fcVoltage, fcCurrent, consumption, probes,
                maxHydrogenTempC, maxHydrogenTempProbeId,
                maxHydrogenConcentration, maxHydrogenConcentrationProbeId,
                maxHydrogenPressure, maxHydrogenPressureProbeId,
                hvDcDcStatus);
    }
}
