#pragma once
#include "./basic_types.hpp"
#include "./registration.hpp"

namespace lsp::protocol
{
    struct TextDocumentSyncClientCapabilities
    {
        boolean dynamicRegistration;
        std::optional<boolean> willSave;
        std::optional<boolean> willSaveWaitUntil;
        std::optional<boolean> didSave;
    };

    enum class TextDocumentSyncKind
    {
        None = 0,
        Full = 1,
        Incremental = 2
    };

    struct TextDocumentSyncOptions
    {
        std::optional<boolean> openClose;
        std::optional<TextDocumentSyncKind> change;
    };

    struct TextDocumentItem
    {
        DocumentUri uri;
        string languageId;
        integer version;
        string text;
    };

    struct TextDocumentIdentifier
    {
        DocumentUri uri;
    };

    struct VersionedTextDocumentIdentifier : TextDocumentIdentifier
    {
        integer version;
    };

    struct OptionalVersionedTextDocumentIdentifier : TextDocumentIdentifier
    {
        std::optional<integer> version;
    };

    struct TextDocumentPositionParams
    {
        TextDocumentIdentifier textDocument;
        Position position;
    };

    struct DidOpenTextDocumentParams
    {
        TextDocumentItem textDocument;
    };

    struct TextDocumentChangeRegistrationOptions : TextDocumentRegistrationOptions
    {
        TextDocumentSyncKind syncKind;
    };

    struct TextDocumentContentChangeEvent
    {
        Range range;
        std::optional<uinteger> rangeLength;
        string text;
    };

    struct DidChangeTextDocumentParams
    {
        VersionedTextDocumentIdentifier textDocument;
        std::vector<TextDocumentContentChangeEvent> contentChanges;
    };

    enum class TextDocumentSaveReason
    {
        Manual = 1,
        AfterDelay = 2,
        FocusOut = 3
    };

    struct WillSaveTextDocumentParams
    {
        TextDocumentIdentifier textDocument;
        TextDocumentSaveReason reason;
    };

    struct SaveOptions
    {
        std::optional<boolean> includeText;
    };

    struct TextDocumentSaveRegistrationOptions : TextDocumentRegistrationOptions
    {
        std::optional<boolean> includeText;
    };

    struct DidSaveTextDocumentParams
    {
        TextDocumentIdentifier textDocument;
        std::optional<string> text;
    };

    struct DidCloseTextDocumentParams
    {
        TextDocumentIdentifier textDocument;
    };

    struct TextDocumentEdit
    {
        // OptionalVersionedTextDocumentIdentifier textDocument;
        std::variant<std::vector<TextEdit>, std::vector<AnnotatedTextEdit>, std::vector<SnippetTextEdit>> edits;
    };

}
