/* Copyright 2022, Contributors To LensorOS.
* All rights reserved.
*
* This file is part of LensorOS.
*
* LensorOS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LensorOS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LensorOS. If not, see <https://www.gnu.org/licenses
 */

#ifndef _LENSOROS_FORMAT
#define _LENSOROS_FORMAT

#include <string>
#include <concepts>
#include <cstring>
#include <bits/terminate.h>
#include <type_traits>
#include <array>
#include <memory>
#include <ctype.h>

#ifndef __kernel__
#    include <stdio.h>
#else
#    include <debug.h>
#endif

namespace std {
/// ===========================================================================
///  Helpers, forward decls, and typedefs.
/// ===========================================================================
template <typename _Char, typename... _Args>
class basic_format_string;

template <typename _Char>
struct basic_format_parse_context;

template <typename _Output, typename _Char>
struct basic_format_context;

template <typename _Char>
class basic_format_arg;

template <typename _Char>
class basic_format_args;

template <typename _Type, typename _Char = char>
struct formatter { formatter() = delete; };

namespace __detail {
[[maybe_unused]]
inline constexpr void __make_not_constexpr(bool __b = true) noexcept {
    if (__b) { __builtin_unreachable(); }
}

/// Stop compilation if the format string is invalid.
///
/// The default parameter is to trick the compiler into compiling this
/// because a constexpr function must contain at least one constexpr code
/// path.
inline void __invalid_format_string(bool __b = true, const char* __msg = "") {
    if (__b) { __terminate_with_message(__msg); }
}

/// This currently doesn’t actually throw.
inline void __throw_format_error([[__maybe_unused__]] const char* __msg = "Invalid format string") {
    __invalid_format_string(true, __msg);
}

/// Tag passed to certain constructors.
struct __parse_only_tag { consteval explicit __parse_only_tag() {} };

/// Parse a number.
template <typename _It>
constexpr size_t __parse_number(_It& __beg) {
    size_t __result = 0;
    while (*__beg != '}' && isdigit(*__beg)) {
        __result = __result * 10 + (*__beg - '0');
        ++__beg;
    }
    return __result;
}

/// This does the actual formatting.
template <typename _Output, typename _Char>
constexpr void __format(basic_format_context<_Output, _Char>&&, basic_string_view<_Char>);

template <typename _It, typename _Dest, typename _Char, typename... _Args>
void __format_to(_Dest&& __dest, basic_string_view<_Char> __fmt, _Args&& ...__args);

/// Inserter for a string.
template <typename _Char>
class __str_insert_iterator {
    string* __str{};

public:
    explicit constexpr __str_insert_iterator() : __str(nullptr) {}
    explicit constexpr __str_insert_iterator(string& __s) : __str(&__s) {}

    __str_insert_iterator& operator=(basic_string_view<_Char> __sv) { return append(__sv); }
    __str_insert_iterator& append(const _Char* __s, size_t __n) { return append({__s, __n}); }
    __str_insert_iterator& append(basic_string_view<_Char> __sv) {
        *__str += __sv;
        return *this;
    }

    /// No-ops.
    constexpr __str_insert_iterator& operator*() { return *this; }
    constexpr __str_insert_iterator& operator++() { return *this; }
    constexpr __str_insert_iterator operator++(int) { return *this; }
};

/// Iterator that does nothing. This is used for typechecking format strings.
template <typename _Char>
struct __nop_insert_iterator {
    explicit constexpr __nop_insert_iterator() {}
    constexpr __nop_insert_iterator& operator=(basic_string_view<_Char>) { return *this; }
    constexpr __nop_insert_iterator& append(basic_string_view<_Char>) { return *this; }
    constexpr __nop_insert_iterator& append(const _Char*, size_t) { return *this; }

    /// No-ops.
    constexpr __nop_insert_iterator& operator*() { return *this; }
    constexpr __nop_insert_iterator& operator++() { return *this; }
    constexpr __nop_insert_iterator operator++(int) { return *this; }
};

#ifndef __kernel__

/// Iterator that appends to a file.
class __file_insert_iterator {
    FILE* __file{};
public:
    explicit constexpr __file_insert_iterator() : __file(nullptr) {}
    explicit constexpr __file_insert_iterator(FILE* __f) : __file(__f) {}

    __file_insert_iterator& operator=(string_view __sv) { return append(__sv); }
    __file_insert_iterator& append(const char* __s, size_t __n) { return append({__s, __n}); }
    __file_insert_iterator& append(string_view __sv) {
        fwrite(__sv.data(), 1, __sv.size(), __file);
        return *this;
    }

    /// No-ops.
    constexpr __file_insert_iterator& operator*() { return *this; }
    constexpr __file_insert_iterator& operator++() { return *this; }
    constexpr __file_insert_iterator operator++(int) { return *this; }
};

#else

/// Iterator that appends to the kernel log.
struct __kernel_log_insert_iterator {
    explicit constexpr __kernel_log_insert_iterator() {}

    __kernel_log_insert_iterator& operator=(string_view __sv) { return append(__sv); }
    __kernel_log_insert_iterator& append(const char* __s, size_t __n) { return append({__s, __n}); }
    __kernel_log_insert_iterator& append(string_view __sv) {
        dbgmsg_buf(reinterpret_cast<const uint8_t*>(__sv.data()), __sv.size());
        return *this;
    }

    /// No-ops.
    constexpr __kernel_log_insert_iterator& operator*() { return *this; }
    constexpr __kernel_log_insert_iterator& operator++() { return *this; }
    constexpr __kernel_log_insert_iterator operator++(int) { return *this; }
};

#endif

}

template <typename... _Args>
using format_string = basic_format_string<char, type_identity_t<_Args>...>;
using format_context = basic_format_context<__detail::__str_insert_iterator<char>, char>;
using format_parse_context = basic_format_parse_context<char>;

/// ===========================================================================
///  Format (parse) context.
/// ===========================================================================
/// Most of the nonsense in this struct that is currently commented out
/// is there because the standard requires it, but I have no idea what
/// in the world it expects me to do with it.
template <typename _Char>
struct basic_format_parse_context {
    using char_type = _Char;
    using const_iterator = typename basic_string_view<_Char>::const_iterator;
    using iterator = const_iterator;

private:
    iterator __begin{};
    iterator __end{};
    /*size_t __next_arg_id{};
    size_t __num_args{};*/
    /*enum struct __indexing { __unknown, __automatic, __manual } __idxing{__indexing::none};*/

public:
    constexpr explicit basic_format_parse_context(basic_string_view<_Char> __fmt, size_t = 0) noexcept
        : __begin(__fmt.begin()), __end(__fmt.end())/*, __num_args(__args)*/ {}

    /*constexpr basic_format_parse_context(const basic_format_parse_context&) = delete;
    constexpr basic_format_parse_context& operator=(const basic_format_parse_context&) = delete;*/


    constexpr iterator begin() const noexcept { return __begin; }
    constexpr iterator end() const noexcept { return __end; }
    constexpr void advance_to(iterator __it) { __begin = __it; }

    /*constexpr size_t next_arg_id() noexcept {
        if (__idxing == __indexing::__manual) { __detail::__throw_format_error("Cannot mix automatic and manual indexing"); }
        if (__idxing == __indexing::__unknown) { __idxing = __indexing::__automatic; }
        return -1;
    }
    constexpr void check_arg_id(size_t __id) {
        if (__idxing == __indexing::__automatic) { __detail::__throw_format_error("Cannot mix automatic and manual indexing"); }
        if (__id >= __num_args) { __detail::__make_not_constexpr(); }
        if (__idxing == __indexing::__unknown) { __idxing = __indexing::__manual; }
    }*/
};

template <typename _Output, typename _Char>
struct basic_format_context {
    using char_type = _Char;
    using iterator = _Output;
    template <typename _Ty> using formatter_type = formatter<_Ty, _Char>;

private:
    iterator __out{};
    basic_format_args<basic_format_context> __args{};

public:
    constexpr basic_format_context(iterator __o, basic_format_args<basic_format_context> __a) noexcept
        : __out(__o), __args(__a) {}

    constexpr basic_format_arg<basic_format_context> arg(size_t __id) const { return __args.get(__id); }
    constexpr iterator out() const { return __out; }
    constexpr void advance_to(iterator __it) { __out = __it; }
    constexpr basic_format_args<basic_format_context>& __get_args() { return __args; }
};

/// ===========================================================================
///  Format args.
/// ===========================================================================
template <typename _Ty>
concept __builtin_type_base = is_integral_v<_Ty> ||
                              is_floating_point_v<_Ty> ||
                              is_same_v<_Ty, bool>;

template <typename _Ty>
concept __builtin_type = __builtin_type_base<_Ty> || (is_pointer_v<_Ty> && not __builtin_type_base<remove_pointer_t<_Ty>>);

template <typename _Context>
class basic_format_arg {
    using _Char = typename _Context::char_type;

public:
    class handle {
        const void* __ptr;
        void (*__format)(basic_format_parse_context<_Char>&, _Context&, const void*);

        template <typename _Ty>
        consteval explicit handle(__detail::__parse_only_tag, type_identity<_Ty>) noexcept
            : __ptr(nullptr), __format([](
                basic_format_parse_context<_Char>& __parse_ctx,
                _Context&,
                const void*
            ) consteval {
                  formatter<_Ty, _Char> __f{};
                  __f.parse(__parse_ctx);
            }) {}

        template <typename _Ty>
        constexpr explicit handle(const _Ty& __val) noexcept
            : __ptr(__builtin_addressof(__val)), __format([](
                basic_format_parse_context<_Char>& __parse_ctx,
                _Context& __ctx,
                const void* __p
            ) constexpr {
                formatter<_Ty, _Char> __f{};
                __f.parse(__parse_ctx);
                __f.format(*static_cast<const _Ty*>(__p), __ctx);
            }) {}

        friend class basic_format_arg<_Context>;

    public:
        void format(basic_format_parse_context<_Char>& __parse_ctx, _Context& __ctx) const {
            __format(__parse_ctx, __ctx, __ptr);
        }
    };

    struct __none {};

private:
    enum struct __arg_type {
        __none,
        __character,
        __bool_,
        __u64,
        __i64,
        __vptr,
        __f32,
        __f64,
        __str,
        __handle,
    } __type = __arg_type::__none;

    union __value_type {
        __none __none__{};
        uint64_t __u64;
        int64_t __i64;
        _Char __character;
        bool __bool_;
        const void* __vptr;
        float __f32;
        double __f64;
        basic_string_view<_Char> __str;
        handle __handle;
    } __value{};


public:
    /// Construct a dummy argument.
    template <typename _Ty>
    consteval basic_format_arg(__detail::__parse_only_tag, type_identity<_Ty>) noexcept
       : __type([]() consteval {
          if constexpr (is_same_v<_Ty, bool>) return __arg_type::__bool_;
          else if constexpr (is_signed_v<_Ty>) return __arg_type::__i64;
          else if constexpr (is_unsigned_v<_Ty>) return __arg_type::__u64;
          else if constexpr (is_same_v<_Ty, _Char>) return __arg_type::__character;
          else if constexpr (is_same_v<_Ty, float>) return __arg_type::__f32;
          else if constexpr (is_same_v<_Ty, double>) return __arg_type::__f64;
          else if constexpr (is_convertible_v<_Ty, basic_string_view<_Char>>) return __arg_type::__str;
          else if constexpr (is_same_v<_Ty, void*>) return __arg_type::__vptr;
          else return __arg_type::__handle;
          __builtin_unreachable();
       } ())
       , __value([]() consteval {
          if constexpr (is_same_v<_Ty, bool>) return __value_type{.__bool_ = {} };
          else if constexpr (is_signed_v<_Ty>) return __value_type{.__i64 = {} };
          else if constexpr (is_unsigned_v<_Ty>) return __value_type{.__u64 = {} };
          else if constexpr (is_same_v<_Ty, _Char>) return __value_type{.__character = {} };
          else if constexpr (is_same_v<_Ty, float>) return __value_type{.__f32 = {} };
          else if constexpr (is_same_v<_Ty, double>) return __value_type{.__f64 = {} };
          else if constexpr (is_convertible_v<_Ty, basic_string_view<_Char>>) return __value_type{.__str ={} };
          else if constexpr (is_same_v<_Ty, void*>) return __value_type{.__vptr = nullptr };
          else return __value_type{.__handle = handle{__detail::__parse_only_tag{}, type_identity<_Ty>{}} };
          __builtin_unreachable();
      }()) {}

    template <typename _Int>
    requires (std::is_signed_v<_Int> and not __char<_Int> and not is_same_v<_Int, bool>)
    constexpr explicit basic_format_arg(_Int __i) : __type(__arg_type::__i64), __value{.__i64 = static_cast<int64_t>(__i)} {}

    template <typename _Int>
    requires (std::is_unsigned_v<_Int> and not __char<_Int> and not is_same_v<_Int, bool>)
    constexpr explicit basic_format_arg(_Int __i) : __type(__arg_type::__u64), __value{.__u64 = static_cast<uint64_t>(__i)} {}

    constexpr explicit basic_format_arg(same_as<bool> auto __b) : __type(__arg_type::__bool_), __value{.__bool_ = __b} {}
    constexpr explicit basic_format_arg(same_as<_Char> auto __c) : __type(__arg_type::__character), __value{.__character = __c} {}
    constexpr explicit basic_format_arg(void* __p) : __type(__arg_type::__vptr), __value{.__vptr = __p} {}
    constexpr explicit basic_format_arg(float __f) : __type(__arg_type::__f32), __value{.__f32 = __f} {}
    constexpr explicit basic_format_arg(double __f) : __type(__arg_type::__f64), __value{.__f64 = __f} {}
    constexpr explicit basic_format_arg(basic_string_view<_Char> __s) : __type(__arg_type::__str), __value{.__str = __s} {}

    template <typename _Ty>
    requires (not __builtin_type<_Ty>)
    constexpr explicit basic_format_arg(const _Ty& __ty) : __type(__arg_type::__handle), __value{.__handle = handle{__ty}} {}

    template <typename _Visitor, typename _Ctx>
    friend constexpr decltype(auto) visit_format_arg(_Visitor&& __vis, basic_format_arg<_Ctx> __arg);

    constexpr basic_format_arg() noexcept {}
    constexpr explicit operator bool() const noexcept { return __type != __arg_type::__none; }
};

template <typename _Context, typename ..._Args>
struct __format_arg_store {
    array<basic_format_arg<_Context>, sizeof...(_Args)> args;

    constexpr __format_arg_store(_Args&&... __args) requires (sizeof...(_Args) > 0)
        : args{basic_format_arg<_Context>(std::forward<_Args>(__args))...} {}

    consteval __format_arg_store() : args{
        basic_format_arg<_Context>{
            __detail::__parse_only_tag{},
            type_identity<remove_cvref_t<_Args>>{}
        }...
    } {}
};

template <typename _Context = format_context, typename ..._Args>
constexpr __format_arg_store<_Context, _Args...> make_format_args(_Args&&... __args) {
    return __format_arg_store<_Context, _Args...> { std::forward<_Args>(__args)... };
}

namespace __detail {
template <typename _Output, typename _Char, typename ..._Args>
constexpr __format_arg_store<basic_format_context<_Output, _Char>, _Args...> __make_args(_Args&&... __args) {
    using _Context = basic_format_context<_Output, _Char>;
    return __format_arg_store<_Context, _Args...> { std::forward<_Args>(__args)... };
}

template <typename _Output, typename _Char, typename ..._Args>
consteval __format_arg_store<basic_format_context<_Output, _Char>, _Args...> __make_dummy_args() {
    using _Context = basic_format_context<_Output, _Char>;
    return __format_arg_store<_Context, _Args...> { };
}
}

template <typename _Context>
class basic_format_args {
    size_t __size{};
    const basic_format_arg<_Context>* __args{};

public:
    constexpr basic_format_args() noexcept {}

    template <typename ..._Args>
    constexpr basic_format_args(const __format_arg_store<_Context, _Args...>& __args) noexcept
        : __size(sizeof...(_Args)), __args(__args.args.data()) {}

    constexpr basic_format_arg<_Context> get(size_t __id) const noexcept {
        return __id < __size ? __args[__id] : basic_format_arg<_Context>{};
    }

    constexpr size_t __sz() const noexcept { return __size; }
};

/// ===========================================================================
///  Formatters.
/// ===========================================================================
/// String view formatter.
template <typename _Char>
struct formatter<basic_string_view<_Char>, _Char> {
    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        if (*__ctx.begin() != '}') { __detail::__throw_format_error("Invalid format specifier in formatter<basic_string_view<_Char>>"); }
        return __ctx.begin();
    }

    template <typename _Ctx>
    auto format(basic_string_view<_Char> __str, _Ctx& __ctx) {
        return __ctx.out().append(__str.data(), __str.size());
    }
};

/// String formatter.
template <typename _Char>
struct formatter<string, _Char> : formatter<basic_string_view<_Char>, _Char> {};

/// String literal formatter.
template <typename _Char, size_t __size>
struct formatter<_Char[__size], _Char> : formatter<basic_string_view<_Char>, _Char> {
    template <typename _Ctx>
    auto format(const _Char* __str, _Ctx& __ctx) {
        return formatter<basic_string_view<_Char>, _Char>::format(basic_string_view<_Char>{__str, __size - 1}, __ctx);
    }
};

/// C-style string formatter.
template <typename _Char>
struct formatter<const _Char*, _Char> : formatter<basic_string_view<_Char>, _Char> {
    template <typename _Ctx>
    auto format(const _Char* __str, _Ctx& __ctx) {
        return formatter<basic_string_view<_Char>, _Char>::format(basic_string_view<_Char>{__str}, __ctx);
    }
};

/// char* formatter.
template <typename _Char>
struct formatter<_Char*, _Char> : formatter<const _Char*, _Char> {};

/// Char formatter.
template <typename _Char>
struct formatter<_Char, _Char> {
    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        if (*__ctx.begin() != '}') { __detail::__invalid_format_string(); }
        return __ctx.begin();
    }

    template <typename _Ctx>
    auto format(_Char __c, _Ctx& __ctx) { return __ctx.out().append(&__c, 1); }
};

/// Bool formatter.
template <typename _Char>
struct formatter<bool, _Char> {
    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        if (*__ctx.begin() != '}') { __detail::__invalid_format_string(); }
        return __ctx.begin();
    }

    template <typename _Ctx>
    auto format(bool __b, _Ctx& __ctx) {
        return __ctx.out().append(__b ? "true" : "false");
    }
};

/// Disallow formatting other char types.
template <__char _Character, typename _Char>
requires (not std::is_same_v<_Character, _Char>)
struct formatter<_Character, _Char> { formatter() = delete; };

/// Void*/nullptr formatter.
template <__abstract_pointer _Ty, typename _Char>
struct formatter<_Ty, _Char> {
    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        if (*__ctx.begin() != '}') { __detail::__invalid_format_string(); }
        return __ctx.begin();
    }

    template <typename _Ctx>
    auto format(_Ty __ptr, _Ctx& __ctx) {
        return __detail::__format_to<typename _Ctx::iterator>(__ctx.out(), basic_string_view<_Char>{"{:#16x}"}, uintptr_t(__ptr));
    }
};

/// Integer formatter.
template <integral _Type, typename _Char>
requires (not __char<_Type>)
struct formatter<_Type, _Char> {
    /// Integer format.
    enum struct __format : uint8_t {
        __bin = 2,
        __oct = 8,
        __dec = 10,
        __hex = 16,
    } __fmt = __format::__dec;

    /// Alternative representation.
    bool __alt = false;

    /// Uppercase hex/binary.
    bool __upper = false;

    /// Width. 0 means no padding.
    size_t __width = 0;

    /// Parse the format string.
    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        auto __beg = __ctx.begin();

        /// '#' is allowed before {xXbBo}.
        if (*__beg == '#') {
            __alt = true;
            __beg++;
        }

        /// Parse a width.
        if (isdigit(*__beg)) { __width = __detail::__parse_number(__beg); }

        /// Parse the format.
        switch (*__beg++) {
            case '}':
                if (__alt) { __detail::__throw_format_error("{:#} is not a valid format specifier"); }
                return __ctx.end();
            case 'd':
                if (__alt) { __detail::__invalid_format_string(); }
                break;
            case 'o': __fmt = __format::__oct; break;
            case 'B': __upper = true; [[fallthrough]];
            case 'b': __fmt = __format::__bin; break;
            case 'X': __upper = true; [[fallthrough]];
            case 'x': __fmt = __format::__hex; break;
            default: __detail::__invalid_format_string();
        }

        if (*__beg != '}') { __detail::__invalid_format_string(); }
        return __beg;
    }

    template <typename _Ctx>
    auto format(_Type __val, _Ctx& __ctx) {
        auto __out = __ctx.out();

        /// Append the minus.
        if constexpr (std::is_signed_v<_Type>) {
            if (__val < 0) {
                __out.append("-", 1);
                __val = -__val;
            }
        }

        /// Append the prefix if we’re using the alternative representation.
        if (__alt) {
            switch (__fmt) {
                case __format::__dec: __detail::__throw_format_error("Invalid state in integer formatter."); break;
                case __format::__oct: __out.append("0", 1); break;
                case __format::__bin: __out.append(__upper ? "0B" : "0b", 2); break;
                case __format::__hex: __out.append(__upper ? "0X" : "0x", 2); break;
            }
        }

        /// Append the number.
        auto __num = __to_string<_Char>(__val, static_cast<uint8_t>(__fmt), __upper);
        if (auto __wd = __width; __wd > __num.size()) {
            __wd -= __num.size();
            while (__wd --> 0) __out.append("0", 1);
        }
        __out.append(__num);
        return __out;
    }
};

/// Floating-point formatter.
template <floating_point _Type, typename _Char>
struct formatter<_Type, _Char> {
    size_t precision;

    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        auto __beg = __ctx.begin();
        if (*__beg == '.') {
            __beg++;
            if (isdigit(*__beg)) precision = __detail::__parse_number(__beg);
            else __detail::__throw_format_error("Invalid precision in floating-point formatter.");
        }
        if (*__beg != '}') __detail::__invalid_format_string();
        return __beg;
    }

    template <typename _Ctx>
    auto format(_Type __val, _Ctx& __ctx) {
        auto __out = __ctx.out();
        __out.append(__to_string<_Char>(__val, precision));
        return __out;
    }
};


#ifdef __lensor__
// BEGIN LENSOR COLOR EXTENSIONS

struct __FG_COLOR {
    string_view __fg_specifier{""};

    __FG_COLOR() = default;
    __FG_COLOR(const string_view& __fg_spec) : __fg_specifier(__fg_spec){}
};
/// __FG_COLOR formatter
template <typename _Char>
struct formatter<__FG_COLOR, _Char> {
    string_view __data{};
    bool __clear_after{ true };

    constexpr auto parse(basic_format_parse_context<_Char>& __ctx) {
        // Just {} with __FG_COLOR means we should just set the terminal color to red.
        if (*__ctx.begin() == '}') {
            __clear_after = false;
            return __ctx.begin();
        }
        size_t offset{ 0 };
        auto __it = __ctx.begin();
        for (; *__it && *__it != '}'; ++__it)
            ++offset;
        __data = string_view{__ctx.begin(), offset};
        return __it;
    }

    template <typename _Ctx>
    auto format(__FG_COLOR __fg_color, _Ctx& __ctx) {
        __ctx.out().append(__fg_color.__fg_specifier);
        if (__clear_after) {
            __ctx.out().append(__data);
            __ctx.out().append("\033[39m");
        }
        return __ctx.out();
    }
};

#define __BG_BLACK "\033[40m"
#define __BG_RED "\033[41m"
#define __BG_GREEN "\033[42m"
#define __BG_YELLOW "\033[43m"
#define __BG_BLUE "\033[44m"
#define __BG_MAGENTA "\033[45m"
#define __BG_CYAN "\033[46m"
#define __BG_WHITE "\033[47m"
#define __BG_DEFAULT "\033[49m"

#define __FG_BLACK "\033[30m"
#define __FG_RED "\033[31m"
#define __FG_GREEN "\033[32m"
#define __FG_YELLOW "\033[33m"
#define __FG_BLUE "\033[34m"
#define __FG_MAGENTA "\033[35m"
#define __FG_CYAN "\033[36m"
#define __FG_WHITE "\033[37m"
#define __FG_DEFAULT "\033[39m"

#define __BLACK   std::__FG_COLOR{__FG_BLACK}
#define __RED     std::__FG_COLOR{__FG_RED}
#define __GREEN   std::__FG_COLOR{__FG_GREEN}
#define __YELLOW  std::__FG_COLOR{__FG_YELLOW}
#define __BLUE    std::__FG_COLOR{__FG_BLUE}
#define __MAGENTA std::__FG_COLOR{__FG_MAGENTA}
#define __CYAN    std::__FG_COLOR{__FG_CYAN}
#define __WHITE   std::__FG_COLOR{__FG_WHITE}
#define __DEFAULT std::__FG_COLOR{__FG_DEFAULT}

#endif // END LENSOR COLOR EXTENSIONS


/// ===========================================================================
///  Formatting functions – Implementation.
/// ===========================================================================
template <typename _Visitor, typename _Context>
constexpr decltype(auto) visit_format_arg(_Visitor&& __vis, basic_format_arg<_Context> __arg) {
    using __arg_ty = basic_format_arg<_Context>;
    using __ty = typename __arg_ty::__arg_type;
    switch (__arg.__type) {
        case __ty::__none: return __vis(typename __arg_ty::__none{});
        case __ty::__bool_: return __vis(__arg.__value.__bool_);
        case __ty::__character: return __vis(__arg.__value.__character);
        case __ty::__u64: return __vis(__arg.__value.__u64);
        case __ty::__i64: return __vis(__arg.__value.__i64);
        case __ty::__vptr: return __vis(__arg.__value.__vptr);
        case __ty::__f32: return __vis(__arg.__value.__f32);
        case __ty::__f64: return __vis(__arg.__value.__f64);
        case __ty::__str: return __vis(__arg.__value.__str);
        case __ty::__handle: return __vis(__arg.__value.__handle);
        default: __detail::__throw_format_error("Invalid format argument type.");
    }
}

namespace __detail {
/// Formatting visitor.
template <typename _Output, typename _Char>
struct __format_visitor {
    using __arg_t = basic_format_arg<basic_format_context<_Output, _Char>>;

    basic_format_parse_context<_Char> __parse_ctx;
    basic_format_context<_Output, _Char>& __ctx;

    constexpr __format_visitor(basic_format_parse_context<_Char>&& __parse_ctx, basic_format_context<_Output, _Char>& __ctx)
        : __parse_ctx(__parse_ctx), __ctx(__ctx) {}

    /// Invalid format arg.
    constexpr void operator()(typename __arg_t::__none) {
        __detail::__throw_format_error("Invalid format argument type.");
    }

    /// Custom format arg.
    constexpr void operator()(typename __arg_t::handle __h) {
        if (!is_constant_evaluated()) __h.format(__parse_ctx, __ctx);
    }

    /// Builtin format args.
    template <typename _Ty>
    constexpr void operator()(_Ty __val) {
        formatter<remove_cvref_t<_Ty>, _Char> __fmt{};
        auto __end = __fmt.parse(__parse_ctx);
        if (__end != __parse_ctx.end()) {
            __throw_format_error("formatter::parse() must consume the entire format specifier");
        }
        if (!is_constant_evaluated()) __fmt.format(__val, __ctx);
    }
};

/// This does the actual formatting.
template <typename _Output, typename _Char>
constexpr void __format(basic_format_context<_Output, _Char>&& __ctx, basic_string_view<_Char> __fmt) {
    /// We start at the beginning of the format string.
    size_t __pos = 0;

    /// Format the arguments.
    for (size_t __i = 0; __i < __ctx.__get_args().__sz(); __i++) {
        size_t __old_pos = __pos;

        /// Find the next unescaped '{' or '}'.
        const auto __find_delim = [&](char __delim) {
            size_t __found;

            /// A format specifier starts with '{', but a double '{{' is an escaped '{'.
            for (;;) {
                /// Find the next '{' or '}'.
                __found = __fmt.find_first_of("{}", __pos);
                if (__found == basic_string_view<_Char>::npos) { __invalid_format_string(); }

                /// Double '{{' or '}}' are escaped.
                if (__fmt[__found] == __fmt[__found + 1]) {
                    __ctx.out() = __fmt.substr(__old_pos, __found - __old_pos + 1);
                    // pos and old_pos are updated here, past the escaped braces.
                    __pos = __old_pos = __found + 2;
                    continue;
                }

                /// If the character is not the one we’re looking for, then that’s an invalid format string.
                if (__fmt[__found] != __delim) { __invalid_format_string(); }
                __pos = __found + 1;
                break;
            }

            return __found;
        };

        /// Advance past format specifier.
        size_t __fmt_spec = __find_delim('{');
        size_t __end = __find_delim('}');

        /// Append the string up to the format specifier.
        __ctx.out() = __fmt.substr(__old_pos, __fmt_spec - __old_pos);

        /// Current format argument.
        auto __arg = __ctx.arg(__i);

        /// Skip a ':' at the start of the format specifier.
        if (__fmt[__fmt_spec + 1] == ':') __fmt_spec++;

        /// Parse and format it.
        basic_format_parse_context<_Char> __parse_ctx{__fmt.substr(__fmt_spec + 1, __end - __fmt_spec - 1)};
        visit_format_arg(__format_visitor{std::move(__parse_ctx), __ctx}, __arg);
    };

    /// Make sure there are no more format specifiers.
    size_t __old_pos = __pos;
    for (;;) {
        __pos = __fmt.find_first_of("{}", __pos);
        if (__pos == string_view::npos) { break; }
        if (__fmt[__pos] != __fmt[__pos + 1]) { __throw_format_error("Excess format specifiers"); }
        else {
            __ctx.out() = __fmt.substr(__old_pos, __pos - __old_pos + 1);
            __pos = __old_pos = __pos + 2;
        }
    }

    /// Append the rest of the string.
    __ctx.out() = __fmt.substr(__old_pos);
}

/// Format to an output using an iterator.
template <typename _It, typename _Dest, typename _Char, typename... _Args>
void __format_to(_Dest&& __dest, basic_string_view<_Char> __fmt, _Args&& ...__args) {
    auto __store = __detail::__make_args<_It, _Char, _Args...>(std::forward<_Args>(__args)...);
    basic_format_context __ctx{_It{std::forward<_Dest>(__dest)}, basic_format_args{__store}};
    __detail::__format(std::move(__ctx), __fmt);
}

}

/// ===========================================================================
///  Formatting functions – API.
/// ===========================================================================
/// Format string
template <typename _Char, typename... _Args>
class basic_format_string {
    basic_string_view<_Char> __sv;

public:
    template <typename _Str>
    requires (convertible_to<const _Str&, basic_string_view<_Char>>)
    consteval basic_format_string(const _Str& __str) : __sv(__str) {
        /// Typecheck the format string.
        using _Output = __detail::__nop_insert_iterator<_Char>;
        auto __store = __detail::__make_dummy_args<_Output, _Char, _Args...>();
        basic_format_context<_Output, _Char> __ctx(_Output{}, basic_format_args{__store});
        __detail::__format(std::move(__ctx), __sv);
    }

    constexpr basic_string_view<_Char> get() const noexcept { return __sv; }
};

/// Format to a string.
template <typename... _Args>
auto vformat(string_view __fmt, _Args&&... __args) -> string {
    using _Output = __detail::__str_insert_iterator<char>;
    string __ret;
    basic_format_context<_Output, char> __ctx(_Output{__ret}, __detail::__make_args<_Output, char, _Args...>(std::forward<_Args>(__args)...));
    __detail::__format(std::move(__ctx), __fmt);
    return __ret;
}

/// Format to a string. The format string is checked at compile time.
template < typename... _Args>
auto format(format_string<_Args...> __str, _Args&&... __args) -> string {
    return vformat(__str.get(), std::forward<_Args>(__args)...);
}

/// Format to an output iterator.
template <typename _Output, typename _Char, typename..._Args>
void vformat_to(_Output&& __out, basic_string_view<_Char> __fmt, _Args&&... __args) {
    __detail::__format_to<_Output>(std::forward<_Output>(__out), __fmt, std::forward<_Args>(__args)...);
}

/// Format to an output iterator. The format string is checked at compile time.
template <typename _Output, typename..._Args>
void format_to(_Output&& __out, format_string<_Args...> __str, _Args&&... __args) {
    vformat_to(std::forward<_Output>(__out), __str.get(), std::forward<_Args>(__args)...);
}

/// ===========================================================================
///  std::print() – User Space.
/// ===========================================================================
#ifndef __kernel__
/// Print to a stream.
template <typename... _Args>
void vprint(FILE* __stream, basic_string_view<char> __fmt, _Args&&... __args) {
    __detail::__format_to<__detail::__file_insert_iterator>(__stream, __fmt, std::forward<_Args>(__args)...);
}

/// Print to stdout.
template <typename... _Args>
void vprint(basic_string_view<char> __fmt, _Args&&... __args) {
    vprint(stdout, __fmt, std::forward<_Args>(__args)...);
}

/// Print to a stream. The format string is checked at compile time.
template <typename... _Args>
void print(FILE* __stream, format_string<_Args...> __fmt, _Args&&... __args) {
    vprint(__stream, __fmt.get(), std::forward<_Args>(__args)...);
}

/// Print to stdout. The format string is checked at compile time.
template <typename... _Args>
void print(format_string<_Args...> __fmt, _Args&&... __args) {
    vprint(__fmt.get(), std::forward<_Args>(__args)...);
}

/// ===========================================================================
///  std::print() – Kernel
/// ===========================================================================
#else
/// Print to the kernel log.
template <typename... _Args>
void vprint(string_view __fmt, _Args&&... __args) {
    using _Output = __detail::__kernel_log_insert_iterator;
    basic_format_context<_Output, char> __ctx(_Output{}, __detail::__make_args<_Output, char, _Args...>(std::forward<_Args>(__args)...));
    __detail::__format(std::move(__ctx), __fmt);
}

/// Print to the kernel log. The format string is checked at compile time.
template <typename... _Args>
void print(format_string<_Args...> __fmt, _Args&&... __args) {
    vprint(__fmt.get(), std::forward<_Args>(__args)...);
}
#endif

}

/// Convenience functions because we need to print u8*’s a lot in the kernel.
#ifdef __kernel__
inline const char* __s(const u8* __s) { return reinterpret_cast<const char*>(__s); }
inline const char* __s(const char* __s) { return __s; }
inline std::string_view __s(const u8* __s, size_t __n) { return {reinterpret_cast<const char*>(__s), __n}; }

template <size_t __sz>
std::string_view __s(const u8 (&__str)[__sz]) { return {reinterpret_cast<const char*>(__str), __sz}; }
#endif

#endif // _LENSOROS_FORMAT
