/*
 * Copyright (c) 2016-2018 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __ARM_COMPUTE_ERROR_H__
#define __ARM_COMPUTE_ERROR_H__

#include <stdarg.h>
#include <string>

namespace arm_compute
{
/** Ignores unused arguments
 *
 * @tparam T Argument types
 *
 * @param[in] ... Ignored arguments
 */
template <typename... T>
inline void ignore_unused(T &&...)
{
}

/** Available error codes */
enum class ErrorCode
{
    OK,                       /**< No error */
    RUNTIME_ERROR,            /**< Generic runtime error */
    UNSUPPORTED_EXTENSION_USE /**< Unsupported extension used*/
};

/** Status class */
class Status
{
public:
    /** Default Constructor **/
    Status()
        : _code(ErrorCode::OK), _error_description(" ")
    {
    }
    /** Default Constructor
     *
     * @param error_status      Error status.
     * @param error_description (Optional) Error description if error_status is not valid.
     */
    explicit Status(ErrorCode error_status, std::string error_description = " ")
        : _code(error_status), _error_description(error_description)
    {
    }
    /** Allow instances of this class to be copy constructed */
    Status(const Status &) = default;
    /** Allow instances of this class to be move constructed */
    Status(Status &&) = default;
    /** Allow instances of this class to be copy assigned */
    Status &operator=(const Status &) = default;
    /** Allow instances of this class to be move assigned */
    Status &operator=(Status &&) = default;
    /** Explicit bool conversion operator
     *
     * @return True if there is no error else false
     */
    explicit operator bool() const noexcept
    {
        return _code == ErrorCode::OK;
    }
    /** Gets error code
     *
     * @return Error code.
     */
    ErrorCode error_code() const
    {
        return _code;
    }
    /** Gets error description if any
     *
     * @return Error description.
     */
    std::string error_description() const
    {
        return _error_description;
    }
    /** Throws a runtime exception in case it contains a valid error status */
    void throw_if_error() const
    {
        if(!bool(*this))
        {
            internal_throw_on_error();
        }
    }

private:
    /** Internal throwing function */
    [[noreturn]] void internal_throw_on_error() const;

private:
    ErrorCode   _code;
    std::string _error_description;
};

/** Creates an error containing the error message from variable argument list
 *
 * @param[in] error_code Error code
 * @param[in] function   Function in which the error occurred.
 * @param[in] file       Name of the file where the error occurred.
 * @param[in] line       Line on which the error occurred.
 * @param[in] msg        Message to display before aborting.
 * @param[in] args       Variable argument list of the message.
 *
 * @return status containing the error
 */
Status create_error_va_list(ErrorCode error_code, const char *function, const char *file, const int line, const char *msg, va_list args);
/** Creates an error containing the error message
 *
 * @param[in] error_code Error code
 * @param[in] function   Function in which the error occurred.
 * @param[in] file       Name of the file where the error occurred.
 * @param[in] line       Line on which the error occurred.
 * @param[in] msg        Message to display before aborting.
 * @param[in] ...        Variable number of arguments of the message.
 *
 * @return status containing the error
 */
Status create_error(ErrorCode error_code, const char *function, const char *file, const int line, const char *msg, ...);
/** Print an error message then throw an std::runtime_error
 *
 * @param[in] function Function in which the error occurred.
 * @param[in] file     Name of the file where the error occurred.
 * @param[in] line     Line on which the error occurred.
 * @param[in] msg      Message to display before aborting.
 * @param[in] ...      Variable number of arguments of the message.
 */
[[noreturn]] void error(const char *function, const char *file, const int line, const char *msg, ...);
}
/** To avoid unused variables warnings
 *
 * This is useful if for example a variable is only used
 * in debug builds and generates a warning in release builds.
 *
 * @param[in] ... Variables which are unused.
 */
#define ARM_COMPUTE_UNUSED(...) ::arm_compute::ignore_unused(__VA_ARGS__) // NOLINT

/** Creates an error with a given message
 *
 * @param[in] error_code Error code.
 * @param[in] ...        Message to encapsulate.
 */
#define ARM_COMPUTE_CREATE_ERROR(error_code, ...) ::arm_compute::create_error(error_code, __func__, __FILE__, __LINE__, __VA_ARGS__) // NOLINT

/** Creates an error on location with a given message
 *
 * @param[in] error_code Error code.
 * @param[in] func       Function in which the error occurred.
 * @param[in] file       File in which the error occurred.
 * @param[in] line       Line in which the error occurred.
 * @param[in] ...        Message to display before aborting.
 */
#define ARM_COMPUTE_CREATE_ERROR_LOC(error_code, func, file, line, ...) ::arm_compute::create_error(error_code, func, file, line, __VA_ARGS__) // NOLINT

/** An error is returned with the given description.
 *
 * @param[in] ... Error description message.
 */
#define ARM_COMPUTE_RETURN_ERROR_MSG(...)                                                    \
    do                                                                                       \
    {                                                                                        \
        return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, __VA_ARGS__); \
    } while(false)

/** Checks if a status contains an error and returns it
 *
 * @param[in] status Status value to check
 */
#define ARM_COMPUTE_RETURN_ON_ERROR(status) \
    do                                      \
    {                                       \
        if(!bool(status))                   \
        {                                   \
            return status;                  \
        }                                   \
    } while(false)

/** Checks if an error value is valid if not throws an exception with the error
 *
 * @param[in] error Error value to check.
 */
#define ARM_COMPUTE_THROW_ON_ERROR(error) \
    error.throw_if_error();

/** If the condition is true, an error is returned
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] ...  Error description message
 */
#define ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, ...)                                               \
    do                                                                                           \
    {                                                                                            \
        if(cond)                                                                                 \
        {                                                                                        \
            return ARM_COMPUTE_CREATE_ERROR(arm_compute::ErrorCode::RUNTIME_ERROR, __VA_ARGS__); \
        }                                                                                        \
    } while(false)

/** If the condition is true, an error is thrown
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] func Function in which the error occurred.
 * @param[in] file File in which the error occurred.
 * @param[in] line Line in which the error occurred.
 * @param[in] ...  Error description message.
 */
#define ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, ...)                                               \
    do                                                                                                                 \
    {                                                                                                                  \
        if(cond)                                                                                                       \
        {                                                                                                              \
            return ARM_COMPUTE_CREATE_ERROR_LOC(arm_compute::ErrorCode::RUNTIME_ERROR, func, file, line, __VA_ARGS__); \
        }                                                                                                              \
    } while(false)

/** If the condition is true, an error is returned
 *
 * @param[in] cond Condition to evaluate
 */
#define ARM_COMPUTE_RETURN_ERROR_ON(cond) \
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(cond, #cond)

/** If the condition is true, an error is returned
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] func Function in which the error occurred.
 * @param[in] file File in which the error occurred.
 * @param[in] line Line in which the error occurred.
 */
#define ARM_COMPUTE_RETURN_ERROR_ON_LOC(cond, func, file, line) \
    ARM_COMPUTE_RETURN_ERROR_ON_LOC_MSG(cond, func, file, line, #cond)

/** Print the given message then throw an std::runtime_error.
 *
 * @param[in] ... Message to display before aborting.
 */
#define ARM_COMPUTE_ERROR(...) ::arm_compute::error(__func__, __FILE__, __LINE__, __VA_ARGS__) // NOLINT

/** Print the given message then throw an std::runtime_error.
 *
 * @param[in] func Function in which the error occurred.
 * @param[in] file File in which the error occurred.
 * @param[in] line Line in which the error occurred.
 * @param[in] ...  Message to display before aborting.
 */
#define ARM_COMPUTE_ERROR_LOC(func, file, line, ...) ::arm_compute::error(func, file, line, __VA_ARGS__) // NOLINT

/** If the condition is true, the given message is printed and program exits
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] ...  Message to print if cond is false.
 */
#define ARM_COMPUTE_EXIT_ON_MSG(cond, ...)  \
    do                                      \
    {                                       \
        if(cond)                            \
        {                                   \
            ARM_COMPUTE_ERROR(__VA_ARGS__); \
        }                                   \
    } while(false)

#ifdef ARM_COMPUTE_ASSERTS_ENABLED
/** Checks if a status value is valid if not throws an exception with the error
 *
 * @param[in] status Status value to check.
 */
#define ARM_COMPUTE_ERROR_THROW_ON(status) \
    status.throw_if_error()

/** If the condition is true, the given message is printed and an exception is thrown
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] ...  Message to print if cond is false.
 */
#define ARM_COMPUTE_ERROR_ON_MSG(cond, ...) \
    ARM_COMPUTE_EXIT_ON_MSG(cond, __VA_ARGS__)

/** If the condition is true, the given message is printed and an exception is thrown
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] func Function in which the error occurred.
 * @param[in] file File in which the error occurred.
 * @param[in] line Line in which the error occurred.
 * @param[in] ...  Message to print if cond is false.
 */
#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...) \
    do                                                            \
    {                                                             \
        if(cond)                                                  \
        {                                                         \
            ARM_COMPUTE_ERROR_LOC(func, file, line, __VA_ARGS__); \
        }                                                         \
    } while(false)

/** If the condition is true, the given message is printed and an exception is thrown, otherwise value is returned
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] val  Value to be returned.
 * @param[in] msg  Message to print if cond is false.
 */
#define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) (cond) ? throw std::logic_error(msg) : val;
#else /* ARM_COMPUTE_ASSERTS_ENABLED */
#define ARM_COMPUTE_ERROR_THROW_ON(status)
#define ARM_COMPUTE_ERROR_ON_MSG(cond, ...)
#define ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, ...)
#define ARM_COMPUTE_CONST_ON_ERROR(cond, val, msg) val
#endif /* ARM_COMPUTE_ASSERTS_ENABLED */

/** If the condition is true then an error message is printed and an exception thrown
 *
 * @param[in] cond Condition to evaluate.
 */
#define ARM_COMPUTE_ERROR_ON(cond) \
    ARM_COMPUTE_ERROR_ON_MSG(cond, #cond)

/** If the condition is true then an error message is printed and an exception thrown
 *
 * @param[in] cond Condition to evaluate.
 * @param[in] func Function in which the error occurred.
 * @param[in] file File in which the error occurred.
 * @param[in] line Line in which the error occurred.
 */
#define ARM_COMPUTE_ERROR_ON_LOC(cond, func, file, line) \
    ARM_COMPUTE_ERROR_ON_LOC_MSG(cond, func, file, line, #cond)

#endif /* __ARM_COMPUTE_ERROR_H__ */
