#pragma once

#include "LibLsp/JsonRpc/RequestInMessage.h"
#include "LibLsp/JsonRpc/lsResponseMessage.h"
#include "LibLsp/lsp/lsTextDocumentPositionParams.h"
#include "LibLsp/lsp/symbol.h"
#include "LibLsp/lsp/lsAny.h"
#include "../ProjConfig.h"
/**
	 * The {@code textDocument/typeHierarchy} request is sent from the client to the
	 * server to retrieve a {@link TypeHierarchyItem type hierarchy item} based on
	 * the {@link TypeHierarchyParams cursor position in the text document}. This
	 * request would also allow to specify if the item should be resolved and
	 * whether sub- or supertypes are to be resolved. If no type hierarchy item can
	 * be found under the given text document position, resolves to {@code null}.
	 *
	 * <p>
	 * <b>Note:</b> the <a href=
	 * "https://github.com/Microsoft/vscode-languageserver-node/pull/426">{@code textDocument/typeHierarchy}
	 * language feature</a> is not yet part of the official LSP specification.
	 */
enum class TypeHierarchyDirection :  uint32_t{

	/**
	 * Flag for retrieving/resolving the subtypes. Value: {@code 0}.
	 */
	Children = 0,

	/**
	 * Flag to use when retrieving/resolving the supertypes. Value: {@code 1}.
	 */
	 Parents =1,

	 /**
	  * Flag for resolving both the super- and subtypes. Value: {@code 2}.
	  */
	  Both=2
};
void LSP_EXPORT Reflect(Reader& reader, TypeHierarchyDirection& value);


void LSP_EXPORT Reflect(Writer& writer, TypeHierarchyDirection& value);

struct TypeHierarchyParams :public lsTextDocumentPositionParams
{
	boost::optional<int>  resolve;
	boost::optional<TypeHierarchyDirection> direction ;
	
	MAKE_SWAP_METHOD(TypeHierarchyParams, textDocument, position, resolve, direction)
};
MAKE_REFLECT_STRUCT(TypeHierarchyParams,  textDocument, position, resolve, direction);





/**
 * Representation of an item that carries type information (such as class, interface, enumeration, etc) with additional parentage details.
 */

struct  TypeHierarchyItem {
	/**
	 * The human readable name of the hierarchy item.
	 */

	std::string name;

	/**
	 * Optional detail for the hierarchy item. It can be, for instance, the signature of a function or method.
	 */
	boost::optional<std::string>
	 detail;

	/**
	 * The kind of the hierarchy item. For instance, class or interface.
	 */

	SymbolKind kind;

	/**
	 * {@code true} if the hierarchy item is deprecated. Otherwise, {@code false}. It is {@code false} by default.
	 */
	
	boost::optional<bool> deprecated;

	/**
	 * The URI of the text document where this type hierarchy item belongs to.
	 */

	lsDocumentUri uri;

	/**
	 * The range enclosing this type hierarchy item not including leading/trailing whitespace but everything else
	 * like comments. This information is typically used to determine if the clients cursor is inside the type
	 * hierarchy item to reveal in the symbol in the UI.
	 *
	 * @see TypeHierarchyItem#selectionRange
	 */

	lsRange range;

	/**
	 * The range that should be selected and revealed when this type hierarchy item is being picked, e.g the name of a function.
	 * Must be contained by the the {@link TypeHierarchyItem#getRange range}.
	 *
	 * @see TypeHierarchyItem#range
	 */

	lsRange selectionRange;

	/**
	 * If this type hierarchy item is resolved, it contains the direct parents. Could be empty if the item does not have any
	 * direct parents. If not defined, the parents have not been resolved yet.
	 */
	boost::optional< std::vector<TypeHierarchyItem> >  parents;

	/**
	 * If this type hierarchy item is resolved, it contains the direct children of the current item.
	 * Could be empty if the item does not have any descendants. If not defined, the children have not been resolved.
	 */
	boost::optional< std::vector<TypeHierarchyItem> >  children;

	/**
 * An boost::optional data field can be used to identify a type hierarchy item in a resolve request.
 */
	boost::optional<lsp::Any> data;

	MAKE_SWAP_METHOD(TypeHierarchyItem, name, detail, kind, deprecated, uri, range, selectionRange, parents, children, data)
};
MAKE_REFLECT_STRUCT(TypeHierarchyItem, name, detail, kind, deprecated, uri, range, selectionRange, parents, children, data);



DEFINE_REQUEST_RESPONSE_TYPE(td_typeHierarchy, TypeHierarchyParams, TypeHierarchyItem, "textDocument/typeHierarchy");