package com.lingniu.ingest.protocol.gb32960.codec.parser.vendor.guangdong;

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;

/**
 * 广东燃料电池规范 §7.2.3.5 表 15/16：辅助系统数据。typeCode {@code 0x31}。变长。
 *
 * <pre>
 *   subSystemCount(1)
 *   For each:
 *     airCompressorMotorVoltageV(2, 0.1V, 0~1000V)
 *     airCompressorPowerKw(2, offset -5, 1 kw, range -5~+30)
 *     hydrogenPumpMotorVoltageV(2, 0.2V, 0~50V)
 *     hydrogenPumpPowerKw(2, offset -5, 1 kw)
 *     waterPumpVoltageV(2, 0.1V)
 *     ptcVoltageV(2, 0.1V)
 *     ptcPowerKw(2, offset -5, 1 kw)
 *     lowVoltageBatteryVoltageV(2, 0.1V, 0~32V)
 * </pre>
 *
 * 每子系统 16 字节。
 */
public final class GdFcAuxiliaryBlockParser implements InfoBlockParser {

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

    @Override
    public InfoBlock parse(ByteBuffer buf) {
        int count = buf.get() & 0xFF;
        List<InfoBlock.GuangdongFc.Auxiliary.Subsystem> subs = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            Double airCompV = ValueDecoder.scaledU16(buf, 0.1);
            Integer airCompP = readPowerOffsetMinus5(buf);
            Double h2PumpV = ValueDecoder.scaledU16(buf, 0.2);
            Integer h2PumpP = readPowerOffsetMinus5(buf);
            Double waterPumpV = ValueDecoder.scaledU16(buf, 0.1);
            Double ptcV = ValueDecoder.scaledU16(buf, 0.1);
            Integer ptcP = readPowerOffsetMinus5(buf);
            Double lvBattV = ValueDecoder.scaledU16(buf, 0.1);
            subs.add(new InfoBlock.GuangdongFc.Auxiliary.Subsystem(
                    airCompV, airCompP, h2PumpV, h2PumpP, waterPumpV, ptcV, ptcP, lvBattV));
        }
        return new InfoBlock.GuangdongFc.Auxiliary(count, subs);
    }

    /** 功率字段：raw(2B) - 5，0xFFFE/0xFFFF 异常/无效。 */
    private static Integer readPowerOffsetMinus5(ByteBuffer buf) {
        int raw = buf.getShort() & 0xFFFF;
        if (raw == 0xFFFE || raw == 0xFFFF) return null;
        return raw - 5;
    }
}
