using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using JsonRpc.Standard;
using JsonRpc.Standard.Contracts;
using JsonRpc.Standard.Server;
using LanguageServer.VsCode.Contracts;
using Newtonsoft.Json.Linq;
using UpsilonLanguageServer.ReferenceHandler;

// ReSharper disable UnusedMember.Global

namespace UpsilonLanguageServer.Services
{
    public class InitializationService : UpsilonLanguageServiceBase
    {
        [JsonRpcMethod(AllowExtensionData = true)]
        public InitializeResult Initialize(int processId, Uri rootUri, ClientCapabilities capabilities,
            JToken initializationOptions = null, string trace = null)
        {
            try
            {
                WorkspaceService.RootUri = rootUri?.AbsolutePath;
                if (rootUri != null)
                {
                    var configPath      = rootUri.AbsolutePath + "/.upsilon";
                    var typesConfigFile = configPath           + "/types.json";
                    if (File.Exists(typesConfigFile))
                    {
                        BoundTypeParser.LoadBoundTypes(File.ReadAllText(typesConfigFile));
                    }

                    var staticConfigFile = configPath + "/static.json";
                    if (File.Exists(staticConfigFile))
                    {
                        BoundTypeParser.LoadStaticVariables(File.ReadAllText(staticConfigFile));
                    }

                    Session.Settings.ModuleDirectory =
                        new DirectoryInfo(Path.Combine(rootUri.AbsolutePath, Session.Settings.ModuleDirectory))
                            .FullName;

                    var referenceConfigFile = configPath + "/references.json";
                    if (File.Exists(referenceConfigFile))
                    {
                        LoadReferenceLibraries.ReloadReferences(WorkspaceService.RootUri,
                            File.ReadAllText(referenceConfigFile));
                    }
                }
            }
            catch (Exception e)
            {
                Client.Window.ShowMessage(MessageType.Error, e.ToString());
            }
            return new InitializeResult(new ServerCapabilities
            {
                HoverProvider         = true,
                SignatureHelpProvider = new SignatureHelpOptions(new[] {'(', ','}),
                CompletionProvider    = new CompletionOptions(true, "."),
                TextDocumentSync = new TextDocumentSyncOptions
                {
                    OpenClose = true,
                    WillSave  = true,
                    Change    = TextDocumentSyncKind.Incremental
                },
            });
        }

        [JsonRpcMethod(IsNotification = true)]
        public async Task Initialized()
        {
            await Client.Window.ShowMessage(MessageType.Info, "Upsilon Language Server Initialized");
        }

        public void Shutdown()
        {
            Session.StopServer();
        }

        [JsonRpcMethod(IsNotification = true)]
        public void Exit()
        {
            Client.Window.ShowMessage(MessageType.Info, "Upsilon Language Server exited");
            Session.StopServer();
        }

        [JsonRpcMethod("$/cancelRequest", IsNotification = true)]
        public void CancelRequest(MessageId id)
        {
            RequestContext.Features.Get<IRequestCancellationFeature>().TryCancel(id);
        }
    }
}
