#pragma once

#include "LibLsp/lsp/lsDocumentUri.h"
#include "LibLsp/lsp/lsAny.h"
#include "lsClientCapabilities.h"
#include "LibLsp/lsp/workspace/workspaceFolders.h"

struct ClientInfo
{
    std::string name;
    optional<std::string> version;

    MAKE_SWAP_METHOD(ClientInfo, name, version);
};
MAKE_REFLECT_STRUCT(ClientInfo, name, version);

struct lsInitializeParams
{
    // The process Id of the parent process that started
    // the server. Is null if the process has not been started by another process.
    // If the parent process is not alive then the server should exit (see exit
    // notification) its process.
    optional<int> processId;

    /**
   * Information about the client
   *
   * @since 3.15.0
   */
    optional<ClientInfo> clientInfo;
    /**
   * The locale the client is currently showing the user interface
   * in. This must not necessarily be the locale of the operating
   * system.
   *
   * Uses IETF language tags as the value's syntax
   * (See https://en.wikipedia.org/wiki/IETF_language_tag)
   *
   * @since 3.16.0
   */
    optional<std::string> locale;

    // The rootPath of the workspace. Is null
    // if no folder is open.
    //
    // @deprecated in favour of rootUri.
    optional<std::string> rootPath;

    // The rootUri of the workspace. Is null if no
    // folder is open. If both `rootPath` and `rootUri` are set
    // `rootUri` wins.
    optional<lsDocumentUri> rootUri;

    // User provided initialization options.
    optional<lsp::Any> initializationOptions;

    // The capabilities provided by the client (editor or tool)
    lsClientCapabilities capabilities;

    /**
 * An optional extension to the protocol.
 * To tell the server what client (editor) is talking to it.
 */
    // @Deprecated
    optional<std::string> clientName;

    enum class lsTrace
    {
        // NOTE: serialized as a string, one of 'off' | 'messages' | 'verbose';
        Off, // off
        Messages, // messages
        Verbose // verbose
    };

    // The initial trace setting. If omitted trace is disabled ('off').
    lsTrace trace = lsTrace::Off;

    /**
 * The workspace folders configured in the client when the server starts.
 * This property is only available if the client supports workspace folders.
 * It can be `null` if the client supports workspace folders but none are
 * configured.
 *
 * Since 3.6.0
 */
    optional<std::vector<WorkspaceFolder>> workspaceFolders;

    MAKE_SWAP_METHOD(
        lsInitializeParams, processId, rootPath, rootUri, initializationOptions, capabilities, clientName, clientInfo,
        trace, workspaceFolders, locale
    )
};

void Reflect(Reader& reader, lsInitializeParams::lsTrace& value);

void Reflect(Writer& writer, lsInitializeParams::lsTrace& value);

MAKE_REFLECT_STRUCT(
    lsInitializeParams, processId, rootPath, rootUri, initializationOptions, capabilities, clientName, clientInfo,
    trace, workspaceFolders, locale
)

struct lsInitializeError
{
    // Indicates whether the client should retry to send the
    // initilize request after showing the message provided
    // in the ResponseError.
    bool retry;
    void swap(lsInitializeError& arg) noexcept
    {
        auto tem = retry;
        retry = arg.retry;
        arg.retry = tem;
    }
};
MAKE_REFLECT_STRUCT(lsInitializeError, retry);
