/**
 * \file    Mimic_Exception.hpp
 * \author  Silvan Murer
 * \date    24 September 2022
 *
 * \brief   Implementing Exceptions for the Mimic Library
 */

#ifndef INC_MIMIC_EXCEPTION
#define INC_MIMIC_EXCEPTION

#include <stdexcept>

namespace mimic {

/**
 * Base class of the Mimic specific exceptions
 */
class Mimic_Exception : public std::runtime_error {
protected:
    int32_t error_code;     //< Mimic error code

public:
    /**
     * \brief default constructor used to create an exception object
     */
    explicit Mimic_Exception(const std::string& msg, int32_t err_num)
     : std::runtime_error(msg), error_code(err_num)
    {  }

    /**
     * \brief virtual destructor
     */
    virtual ~Mimic_Exception() throw () { }

    /**
     * \brief return the exceptions error code
     * \return error code
     */
    virtual int getErrorNumber() const throw() 
    {
        return error_code;
    }
};

/**
 * OutOfRange exception thrown when a given index value is not available
 */
class Mimic_OutOfRange_Exception : virtual public Mimic_Exception {
public:
    /**
     * \brief default constructor used to create an exception object
     */
    explicit Mimic_OutOfRange_Exception(const std::string& msg, int32_t err_num)
     : Mimic_Exception(msg, err_num)
    {  }

    /**
     * \brief virtual destructor
     */
    virtual ~Mimic_OutOfRange_Exception() throw () { }
};

/**
 * Access exception thrown when an access operation is not allowed on the feature
 */
class Mimic_Access_Exception : virtual public Mimic_Exception {
public:
    /**
     * \brief default constructor used to create an exception object
     */
    explicit Mimic_Access_Exception(const std::string& msg, int32_t err_num)
        : Mimic_Exception(msg, err_num)
    {  }

    /**
     * \brief virtual destructor
     */
    virtual ~Mimic_Access_Exception() throw () { }
};

/**
 * GenTL exception thrown when the GenTL producer dosent support a function
 */
class Mimic_GenTL_Exception : virtual public Mimic_Exception {
public:
    /**
     * \brief default constructor used to create an exception object
     */
    explicit Mimic_GenTL_Exception(const std::string& msg, int32_t err_num)
        : Mimic_Exception(msg, err_num)
    {  }

    /**
     * \brief virtual destructor
     */
    virtual ~Mimic_GenTL_Exception() throw () { }
};

/**
 * Timeout exception thrown when a method call runs into a timeout
 */
class Mimic_Timeout_Exception : virtual public Mimic_Exception {
public:
    /**
     * \brief default constructor used to create an exception object
     */
    explicit Mimic_Timeout_Exception(const std::string& msg, int32_t err_num)
        : Mimic_Exception(msg, err_num)
    {  }

    /**
     * \brief virtual destructor
     */
    virtual ~Mimic_Timeout_Exception() throw () { }
};

} /* namespace mimic */

#endif
