#pragma once

#include "XYEegParserCommon.h"

using XYEegFrame64 = xyparser::XYEegFrame<64>;

class XYEegParser64 final : public xyparser::XYEegTcpParserCommon<64> {
public:
    using Frame = XYEegFrame64;

    enum class FunctionCode : std::uint8_t {
        kImpedance = 0x01,
        kGainSampleRate = 0x02
    };

    enum class ImpedanceSwitch : std::uint8_t {
        kClose = 0x00,
        kOpen = 0x01
    };

    enum class GainSwitch : std::uint8_t {
        k1 = 1,
        k2 = 2,
        k3 = 3,
        k4 = 4,
        k6 = 6,
        k8 = 8,
        k12 = 12,
        k24 = 24
    };

    enum class SampleRateSwitch : std::uint8_t {
        k250 = 0,
        k500 = 1,
        k1000 = 2,
        k2000 = 3
    };

    static constexpr std::size_t kImpedancePayloadSize = 7;
    static constexpr std::size_t kGainSampleRatePayloadSize = 8;
    static constexpr std::size_t kCommandOverheadSize = 7;
    static constexpr std::size_t kImpedanceCommandSize = kImpedancePayloadSize + kCommandOverheadSize;
    static constexpr std::size_t kGainSampleRateCommandSize = kGainSampleRatePayloadSize + kCommandOverheadSize;

    static std::vector<std::uint8_t> SerializeImpedanceCommand(ImpedanceSwitch impedance_switch);
    static std::vector<std::uint8_t> SerializeGainAndSampleRateCommand(GainSwitch gain,
                                                                       SampleRateSwitch sample_rate);

private:
    static std::vector<std::uint8_t> SerializeCommand(FunctionCode function_code,
                                                      const std::vector<std::uint8_t>& payload);
    static std::uint8_t Checksum(const std::vector<std::uint8_t>& bytes,
                                 std::size_t begin_offset,
                                 std::size_t end_offset_exclusive) noexcept;
};
