#pragma once

#include <exception>
#include <string>

#include "xmsdk_export.h"
#include "sensorErrors.h"

namespace xavia::sdk
{
  /**
   * @brief Exception base class for the Xavia SDK exceptions
   * 
   * Extends the standard exception with the 'GetType()' method.
   * Use that method to understand which type of exception is thrown.
   */
  class XMSDK_EXPORT Exception : public std::exception
  {
  public:
    Exception(const std::wstring& i_message, const SensorError i_type = SensorError::UNKNOWN_ERROR);
    Exception(const std::string& i_message, const SensorError i_type = SensorError::UNKNOWN_ERROR);
    virtual ~Exception();

    /**
     * \brief return traditional, human readable version of the exception.
     */
    const char* what() const noexcept override;

    /**
     * \brief Get the type of the exception.
     * \returns Enum indicating exception type. \see SensorError.
     */
    SensorError GetType() const;

  protected:
    void CreateMessage(std::string userMessage);
    std::string  messageUtf8;
    SensorError type;
  };
}

/**!
 * \brief Helper function to easily throw general exceptions. (string version)
 */
[[noreturn]] inline void XM_ERROR(const std::string msg)
{
  throw xavia::sdk::Exception(msg);
}

/**!
 * \brief Helper function to easily throw general exceptions. (wstring version)
 */
[[noreturn]] inline void XM_ERROR(const std::wstring msg)
{
  throw xavia::sdk::Exception(msg);
}
