#pragma once
#include <string>
#include <functional>
#include <vector>
namespace lsp
{
class Log
{
public:
    virtual ~Log() = default;

    enum class Level
    {
        /**
                          * OFF is a special level that can be used to turn off logging.

                          */
        OFF = 0,

        /**
                         * SEVERE is a message level indicating a serious failure.
                         * <p>
                         * In general SEVERE messages should describe events that are
                         * of considerable importance and which will prevent normal
                         * program execution.   They should be reasonably intelligible
                         * to end users and to system administrators.

                         */
        SEVERE = 1,

        /**
                          * WARNING is a message level indicating a potential problem.
                          * <p>
                          * In general WARNING messages should describe events that will
                          * be of interest to end users or system managers, or which
                          * indicate potential problems.

                          *
                          */
        WARNING = 2,
        /**
                         * INFO is a message level for informational messages.
                         * <p>
                         * Typically INFO messages will be written to the console
                         * or its equivalent.  So the INFO level should only be
                         * used for reasonably significant messages that will
                         * make sense to end users and system administrators.

                         */
        INFO = 3,
        /**
                         * CONFIG is a message level for static configuration messages.
                         * <p>
                         * CONFIG messages are intended to provide a variety of static
                         * configuration information, to assist in debugging problems
                         * that may be associated with particular configurations.
                         * For example, CONFIG message might include the CPU type,
                         * the graphics depth, the GUI look-and-feel, etc.
                         * This level is initialized to <CODE>4</CODE>.
                         */

        CONFIG = 4,

        /**
                          * FINE is a message level providing tracing information.
                          * <p>
                          * All of FINE, FINER, and FINEST are intended for relatively
                          * detailed tracing.  The exact meaning of the three levels will
                          * vary between subsystems, but in general, FINEST should be used
                          * for the most voluminous detailed output, FINER for somewhat
                          * less detailed output, and FINE for the  lowest volume (and
                          * most important) messages.
                          * <p>
                          * In general the FINE level should be used for information
                          * that will be broadly interesting to developers who do not have
                          * a specialized interest in the specific subsystem.
                          * <p>
                          * FINE messages might include things like minor (recoverable)
                          * failures.  Issues indicating potential performance problems
                          * are also worth logging as FINE.
                          * This level is initialized to <CODE>5</CODE>.
                          */
        FINE = 5,

        /**
                          * FINER indicates a fairly detailed tracing message.
                          * By default logging calls for entering, returning, or throwing
                          * an exception are traced at this level.
                          * This level is initialized to <CODE>400</CODE>.
                          */
        FINER = 6,

        /**
                           * FINEST indicates a highly detailed tracing message.
                           * This level is initialized to <CODE>300</CODE>.
                           */
        FINEST = 7,

        /**
                                * ALL indicates that all messages should be logged.
                                * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
                                */
        ALL,
    };
    virtual void log(Level level, std::wstring&& msg) = 0;
    virtual void log(Level level, std::wstring const& msg) = 0;
    virtual void log(Level level, std::string&& msg) = 0;
    virtual void log(Level level, std::string const& msg) = 0;

    void info(std::string const& msg)
    {
        log(Level::INFO, msg);
    }
    void info(std::wstring const& msg)
    {
        log(Level::INFO, msg);
    }
    void error(std::string const& msg)
    {
        log(Level::SEVERE, msg);
    }
    void error(std::wstring const& msg)
    {
        log(Level::SEVERE, msg);
    }
    void warning(std::string const& msg)
    {
        log(Level::WARNING, msg);
    }
    void warning(std::wstring const& msg)
    {
        log(Level::WARNING, msg);
    }
};
} // namespace lsp

class MessageIssue
{

public:
    std::string text;

    lsp::Log::Level code;

    MessageIssue(std::string const& text, lsp::Log::Level code) : text(text), code(code)
    {
    }
    MessageIssue(std::string&& text, lsp::Log::Level code) : text(text), code(code)
    {
    }

    std::string getText()
    {
        return text;
    }

    lsp::Log::Level getIssueCode()
    {
        return code;
    }

    std::string toString()
    {
        return getText();
    }
};
class MessageIssueHandler
{
public:
    /**
         * Handle issues found while parsing or validating a message. The list of issues must not be empty.
         */
    virtual ~MessageIssueHandler() = default;

    virtual void handle(std::vector<MessageIssue>&&) = 0;
    virtual void handle(MessageIssue&&) = 0;
};