#define SD_JOURNAL_SUPPRESS_LOCATION

#include <systemd/sd-journal.h>
#include <unistd.h>

#include <phosphor-logging/lg2.hpp>

#include <algorithm>
#include <bitset>
#include <cstdarg>
#include <cstdio>
#include <iostream>
#include <mutex>
#include <source_location>
#include <sstream>
#include <vector>

namespace lg2::details
{
/** Convert unsigned to string using format flags. */
static std::string value_to_string(uint64_t f, uint64_t v)
{
    switch (f & (hex | bin | dec).value)
    {
        // For binary, use bitset<>::to_string.
        // Treat values without a field-length format flag as 64 bit.
        case bin.value:
        {
            switch (f & (field8 | field16 | field32 | field64).value)
            {
                case field8.value:
                {
                    return "0b" + std::bitset<8>(v).to_string();
                }
                case field16.value:
                {
                    return "0b" + std::bitset<16>(v).to_string();
                }
                case field32.value:
                {
                    return "0b" + std::bitset<32>(v).to_string();
                }
                case field64.value:
                default:
                {
                    return "0b" + std::bitset<64>(v).to_string();
                }
            }
        }

        // For hex, use the appropriate sprintf.
        case hex.value:
        {
            char value[19];
            const char* format = nullptr;

            switch (f & (field8 | field16 | field32 | field64).value)
            {
                case field8.value:
                {
                    format = "0x%02" PRIx64;
                    break;
                }

                case field16.value:
                {
                    format = "0x%04" PRIx64;
                    break;
                }

                case field32.value:
                {
                    format = "0x%08" PRIx64;
                    break;
                }

                case field64.value:
                {
                    format = "0x%016" PRIx64;
                    break;
                }

                default:
                {
                    format = "0x%" PRIx64;
                    break;
                }
            }

            snprintf(value, sizeof(value), format, v);
            return value;
        }

        // For dec, use the simple to_string.
        case dec.value:
        default:
        {
            return std::to_string(v);
        }
    }
}

/** Convert signed to string using format flags. */
static std::string value_to_string(uint64_t f, int64_t v)
{
    // If hex or bin was requested just use the unsigned formatting
    // rules. (What should a negative binary number look like otherwise?)
    if (f & (hex | bin).value)
    {
        return value_to_string(f, static_cast<uint64_t>(v));
    }
    return std::to_string(v);
}

/** Convert float to string using format flags. */
static std::string value_to_string(uint64_t, double v)
{
    // No format flags supported for floats.
    return std::to_string(v);
}

// Positions of various strings in an iovec.
static constexpr size_t pos_msg = 0;
static constexpr size_t pos_fmtmsg = 1;
static constexpr size_t pos_prio = 2;
static constexpr size_t pos_file = 3;
static constexpr size_t pos_line = 4;
static constexpr size_t pos_func = 5;
static constexpr size_t static_locs = pos_func + 1;

/** No-op output of a message. */
static void noop_extra_output(level, const std::source_location&,
                              const std::string&)
{}

/** std::cerr output of a message. */
static void cerr_extra_output(level l, const std::source_location& s,
                              const std::string& m)
{
    static const char* const defaultFormat = []() {
        const char* f = getenv("LG2_FORMAT");
        if (nullptr == f)
        {
            f = "<%l> %m";
        }
        return f;
    }();

    const char* format = defaultFormat;

    std::stringstream stream;

    while (*format)
    {
        if (*format != '%')
        {
            stream << *format;
            ++format;
            continue;
        }

        ++format;
        switch (*format)
        {
            case '%':
            case '\0':
                stream << '%';
                break;

            case 'f':
                stream << s.function_name();
                break;

            case 'F':
                stream << s.file_name();
                break;

            case 'l':
                stream << static_cast<uint64_t>(l);
                break;

            case 'L':
                stream << s.line();
                break;

            case 'm':
                stream << m;
                break;

            default:
                stream << '%' << *format;
                break;
        }

        if (*format != '\0')
        {
            ++format;
        }
    }

    static std::mutex mutex;

    // Prevent multiple threads from clobbering the stderr lines of each other
    std::scoped_lock lock(mutex);

    // Ensure this line makes it out before releasing mutex for next line
    std::cerr << stream.str() << std::endl;
}

// Use the cerr output method if we are on a TTY or if explicitly set via
// environment variable.
static auto extra_output_method = (isatty(fileno(stderr)) ||
                                   nullptr != getenv("LG2_FORCE_STDERR"))
                                      ? cerr_extra_output
                                      : noop_extra_output;

// Do_log implementation.
void do_log(level l, const std::source_location& s, const char* m, ...)
{
    using namespace std::string_literals;

    std::vector<std::string> strings{static_locs};

    std::string message{m};

    // Assign all the static fields.
    strings[pos_fmtmsg] = "LOG2_FMTMSG="s + m;
    strings[pos_prio] = "PRIORITY="s + std::to_string(static_cast<uint64_t>(l));
    strings[pos_file] = "CODE_FILE="s + s.file_name();
    strings[pos_line] = "CODE_LINE="s + std::to_string(s.line());
    strings[pos_func] = "CODE_FUNC="s + s.function_name();

    // Handle all the va_list args.
    std::va_list args;
    va_start(args, m);
    while (true)
    {
        // Get the header out.
        auto h_ptr = va_arg(args, const char*);
        if (h_ptr == nullptr)
        {
            break;
        }
        std::string h{h_ptr};

        // Get the format flag.
        auto f = va_arg(args, uint64_t);

        // Handle the value depending on which type format flag it has.
        std::string value = {};
        switch (f & (signed_val | unsigned_val | str | floating).value)
        {
            case signed_val.value:
            {
                auto v = va_arg(args, int64_t);
                value = value_to_string(f, v);
                break;
            }

            case unsigned_val.value:
            {
                auto v = va_arg(args, uint64_t);
                value = value_to_string(f, v);
                break;
            }

            case str.value:
            {
                value = va_arg(args, const char*);
                break;
            }

            case floating.value:
            {
                auto v = va_arg(args, double);
                value = value_to_string(f, v);
                break;
            }
        }

        // Create the field for this value.
        strings.emplace_back(h + '=' + value);

        // Check for {HEADER} in the message and replace with value.
        auto h_brace = '{' + h + '}';
        if (auto start = message.find(h_brace); start != std::string::npos)
        {
            message.replace(start, h_brace.size(), value);
        }
    }
    va_end(args);

    // Add the final message into the strings array.
    strings[pos_msg] = "MESSAGE="s + message.data();

    // Trasform strings -> iovec.
    std::vector<iovec> iov{};
    std::ranges::transform(strings, std::back_inserter(iov), [](auto& s) {
        return iovec{s.data(), s.length()};
    });

    // Output the iovec.
    sd_journal_sendv(iov.data(), strings.size());
    extra_output_method(l, s, message);
}

} // namespace lg2::details
