#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);



