#pragma once

#include "xmsdk_export.h"

#include <cstdint>
#include <string>

namespace xavia::sdk
{
  enum class SensorType {
    XT_G4,
    XL_G6,
    Unknown,
  };

  enum class SensorVariation {
    X30,
    X60,
    X45,
    SL,
    DL,
    FV,
    STANDARD,
    Unknown,
  };

  /**
   * \brief utility class that holds a serial number and allows interpretation.
   */
  class XMSDK_EXPORT SerialNumber
  {
  public:
    explicit SerialNumber(const std::uint8_t* serialNumberHex);
    explicit SerialNumber(const std::uint32_t& serialNumberHex);
    SerialNumber() = default;
    virtual ~SerialNumber();

    constexpr SensorType      GetSensorType() const { return type; }
    constexpr std::uint32_t   GetSensorUID() const { return uid; }
    constexpr SensorVariation GetSensorVariation() const { return variation; }
    constexpr std::uint32_t   GetSensorTypeVersion() const { return version; }
    std::string               ToString() const;
    std::wstring              ToWString() const;
    constexpr std::uint32_t   ToInt() const { return integerRepresentation; }

  private:
    void _DeserializeSerialNumber(const std::uint8_t* serialNumberHex);
    SensorType    _ExtractSensorType(const std::uint8_t* serialNumberHex) const;
    std::uint32_t _ExtractUID(const std::uint8_t* serialNumberHex) const;
    std::uint32_t _ExtractVersion(const std::uint8_t* serialNumberHex) const;
    SensorVariation _ExtractVariation(const std::uint8_t* serialNumberHex) const;
    bool          _ExtractOrientation(const std::uint8_t* serialNumberHex) const;

    // Private members
    SensorType      type{SensorType::XL_G6};
    std::uint32_t   uid{0};
    SensorVariation variation{SensorVariation::X30};
    std::uint32_t   version{0};
    bool            isVertical{false};
    std::uint32_t   integerRepresentation{0};
  };
}
