#pragma once
#include <spdlog/spdlog.h>
#include <sstream>
#include <ostream>

namespace Color
{
    enum Code
    {
        FG_RED = 31,
        FG_GREEN = 32,
        FG_BLUE = 34,
        FG_DEFAULT = 39,
        BG_RED = 41,
        BG_GREEN = 42,
        BG_BLUE = 44,
        BG_DEFAULT = 49
    };
    class Modifier
    {
        Code code;

    public:
        Modifier(Code pCode) : code(pCode) {}
        friend std::ostream &
        operator<<(std::ostream &os, const Modifier &mod)
        {
            return os << "\033[" << mod.code << "m";
        }
    };
}

// -----------------------------------------------------------------------------
//
// Assertions
//
// -----------------------------------------------------------------------------

#define PSDR_ASSERT(condition)                                                             \
    if (!(condition))                                                                      \
    {                                                                                      \
        std::stringstream ss;                                                              \
        ss << "Assertion failed: " << #condition << " in " << __FILE__ << ":" << __LINE__; \
        throw std::runtime_error(ss.str());                                                \
    }

#define PSDR_WARN(condition)                                                               \
    if (!(condition))                                                                      \
    {                                                                                      \
        std::stringstream ss;                                                              \
        ss << "Assertion failed: " << #condition << " in " << __FILE__ << ":" << __LINE__; \
        std::cerr << ss.str() << std::endl;                                                \
    }

#define PSDR_ASSERT_MSG(condition, message)                                              \
    if (!(condition))                                                                    \
    {                                                                                    \
        std::ostringstream oss;                                                          \
        oss << "Assertion failed: " << message << " in " << __FILE__ << ":" << __LINE__; \
        throw std::runtime_error(oss.str());                                             \
    }
