/*******************************************************************************
 * Copyright (c) 2018, 2019 1C-Soft LLC.
 *
 * This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Vladimir Piskarev (1C) - initial API and implementation
 *******************************************************************************/
package org.eclipse.handly.internal.examples.lsp;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.URI;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BooleanSupplier;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.handly.examples.lsp.ILanguageSourceFile;
import org.eclipse.lsp4e.server.StreamConnectionProvider;
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageServer;

/**
 * The manager for language servers.
 */
class ServerManager
{
    /**
     * Should have been private. Package-private for testing purposes only.
     */
    static final int MAX_CONNECTIONS = 16;

    static final ExecutorService THREAD_POOL = Executors.newCachedThreadPool();

    private final Map<String, Language> languages = new HashMap<>();

    private Map<ServerKey, ServerWrapper> servers = new LinkedHashMap<>(16,
        0.75f, true /*access order*/);

    private final AtomicInteger connections = new AtomicInteger();

    /**
     * Returns whether there is a language server registered for the given
     * file extension.
     *
     * @param fileExtension may be <code>null</code>
     * @return <code>true</code> if there is a language server registered for
     *  the given file extension, and <code>false</code> otherwise
     */
    boolean canUseLanguageServer(String fileExtension)
    {
        return languages.containsKey(fileExtension);
    }

    /**
     * Returns a string uniquely identifying the language corresponding to
     * the given file extension.
     *
     * @param fileExtension may be <code>null</code>
     * @return the language identifier, or <code>null</code> if none
     */
    String getLanguageId(String fileExtension)
    {
        Language language = languages.get(fileExtension);
        if (language != null)
            return language.id;
        return null;
    }

    /**
     * Informs the language server that the contents of the given source file
     * is now explicitly managed by the client (a working copy has been opened).
     *
     * @param sourceFile not <code>null</code>
     * @param text not <code>null</code>
     * @throws IllegalArgumentException if there is no registered server for the
     *  given source file
     * @throws IllegalStateException if the given source file is already open
     * @see #update(ILanguageSourceFile, String)
     * @see #updateUri(ILanguageSourceFile)
     * @see #close(ILanguageSourceFile)
     */
    void open(ILanguageSourceFile sourceFile, String text)
    {
        ServerWrapper serverWrapper = getServerWrapper(sourceFile);
        if (serverWrapper == null)
            throw new IllegalArgumentException();
        serverWrapper.open(sourceFile, text);
    }

    /**
     * Informs the language server about the new state of the given source file.
     * Does nothing if the source file is not currently open.
     *
     * @param sourceFile not <code>null</code>
     * @param newText not <code>null</code>
     * @see #open(ILanguageSourceFile, String)
     */
    void update(ILanguageSourceFile sourceFile, String newText)
    {
        ServerWrapper serverWrapper = getServerWrapper(sourceFile);
        if (serverWrapper == null)
            return;
        serverWrapper.update(sourceFile, newText);
    }

    /**
     * Updates the cached URI for the given source file if necessary
     * and informs the language server about the change. Does nothing
     * if the source file is not currently open.
     *
     * @param sourceFile not <code>null</code>
     * @see #open(ILanguageSourceFile, String)
     */
    void updateUri(ILanguageSourceFile sourceFile)
    {
        ServerWrapper serverWrapper = getServerWrapper(sourceFile);
        if (serverWrapper == null)
            return;
        serverWrapper.updateUri(sourceFile);
    }

    /**
     * Informs the language server that the contents of the given source file is
     * no longer explicitly managed by the client (the working copy has been closed).
     * Does nothing if the source file is not currently open.
     *
     * @param sourceFile not <code>null</code>
     * @see #open(ILanguageSourceFile, String)
     */
    void close(ILanguageSourceFile sourceFile)
    {
        ServerWrapper serverWrapper = getServerWrapper(sourceFile);
        if (serverWrapper == null)
            return;
        serverWrapper.close(sourceFile);
    }

    /**
     * Asks the language server to list all symbols found in the given source file.
     *
     * @param sourceFile not <code>null</code>
     * @return the symbols' future (never <code>null</code>)
     * @throws IllegalArgumentException if there is no registered server for the
     *  given source file
     */
    CompletableFuture<List<? extends SymbolInformation>> symbols(
        ILanguageSourceFile sourceFile)
    {
        ServerWrapper serverWrapper = getServerWrapper(sourceFile);
        if (serverWrapper == null)
            throw new IllegalArgumentException();
        return serverWrapper.symbols(sourceFile);
    }

    void startup()
    {
        IConfigurationElement[] elements =
            Platform.getExtensionRegistry().getConfigurationElementsFor(
                Activator.PLUGIN_ID, "languageServers"); //$NON-NLS-1$
        for (IConfigurationElement element : elements)
        {
            if (!"server".equals(element.getName())) //$NON-NLS-1$
                continue;
            ServerDef serverDef = new ServerDef(element);
            IConfigurationElement[] children = element.getChildren("language"); //$NON-NLS-1$
            for (IConfigurationElement child : children)
            {
                Language language = new Language(child.getAttribute("id"), //$NON-NLS-1$
                    serverDef);
                String[] fileExtensions = child.getAttribute(
                    "file-extensions").split(","); //$NON-NLS-1$ //$NON-NLS-2$
                for (String fileExtension : fileExtensions)
                {
                    languages.put(fileExtension.trim(), language);
                }
            }
        }
    }

    synchronized void shutdown()
    {
        servers.values().forEach((s) -> s.disconnect());
        servers = null;
    }

    /**
     * Informs this manager that the given project should no longer be managed
     * (e.g. the project has been closed or removed).
     *
     * @param project not <code>null</code>
     */
    synchronized void disconnect(IProject project)
    {
        servers.forEach((k, s) ->
        {
            if (k.project.equals(project))
                s.disconnect();
        });
    }

    /**
     * Should have been private. Package-private for testing purposes only.
     *
     * @param sourceFile not <code>null</code>
     * @return the server wrapper, or <code>null</code>
     *  if there is no registered server for the given source file
     */
    ServerWrapper getServerWrapper(ILanguageSourceFile sourceFile)
    {
        IFile file = sourceFile.getFile();
        if (file == null)
            return null;
        ServerDef serverDef = getServerDef(file.getFileExtension());
        if (serverDef == null)
            return null;
        return getServerWrapper(new ServerKey(file.getProject(), serverDef));
    }

    private synchronized ServerWrapper getServerWrapper(ServerKey key)
    {
        if (servers == null)
            throw new IllegalStateException();
        ServerWrapper result = servers.get(key);
        if (result == null)
        {
            result = new ServerWrapper(() -> startServer(key.project,
                key.serverDef));
            servers.put(key, result);
        }
        return result;
    }

    private ServerConnection newServerConnection(LanguageServer server,
        CompletableFuture<InitializeResult> initializeFuture,
        BooleanSupplier status, Runnable closer)
    {
        if (connections.incrementAndGet() > MAX_CONNECTIONS)
        {
            // disconnect the least recently used server that is connected
            synchronized (this)
            {
                for (ServerWrapper s : servers.values())
                {
                    if (s.disconnect())
                        break;
                }
            }
        }
        Runnable advisedCloser = () ->
        {
            connections.decrementAndGet();
            closer.run();
        };
        return new ServerConnection(server, initializeFuture, status,
            advisedCloser);
    }

    private ServerConnection startServer(IProject project, ServerDef serverDef)
    {
        URI rootUri = project.getLocationURI();
        if (rootUri == null)
            throw new IllegalArgumentException();
        StreamConnectionProvider streamProvider;
        try
        {
            streamProvider = serverDef.createStreamConnectionProvider();
        }
        catch (CoreException e)
        {
            Activator.logError(e);
            throw new IllegalStateException(e);
        }
        try
        {
            streamProvider.start();
        }
        catch (IOException e)
        {
            throw new UncheckedIOException(e);
        }
        LanguageClient client;
        try
        {
            client = serverDef.createLanguageClient();
        }
        catch (CoreException e)
        {
            Activator.logError(e);
            throw new IllegalStateException(e);
        }
        LanguageServer[] serverSlot = new LanguageServer[1];
        Launcher<LanguageServer> launcher = Launcher.createLauncher(client,
            LanguageServer.class, streamProvider.getInputStream(),
            streamProvider.getOutputStream(), THREAD_POOL,
            consumer -> (message ->
            {
                consumer.consume(message);
                streamProvider.handleMessage(message, serverSlot[0], rootUri);
            }));
        LanguageServer server = serverSlot[0] = launcher.getRemoteProxy();
        Future<?> launcherFuture = launcher.startListening();
        InitializeParams params = new InitializeParams();
        params.setRootUri(rootUri.toString());
        params.setCapabilities(new ClientCapabilities(null, null, null));
        params.setInitializationOptions(streamProvider.getInitializationOptions(
            rootUri));
        CompletableFuture<InitializeResult> initializeFuture =
            server.initialize(params);
        return newServerConnection(server, initializeFuture,
            () -> !launcherFuture.isDone(), () ->
            {
                try
                {
                    server.shutdown().get(10, TimeUnit.SECONDS);
                }
                catch (InterruptedException | ExecutionException
                    | TimeoutException e)
                {
                    e.printStackTrace();
                }
                server.exit();
                streamProvider.stop();
            });
    }

    private ServerDef getServerDef(String fileExtension)
    {
        Language language = languages.get(fileExtension);
        if (language != null)
            return language.serverDef;
        return null;
    }

    private static class Language
    {
        final String id;
        final ServerDef serverDef;

        Language(String id, ServerDef serverDef)
        {
            this.id = Objects.requireNonNull(id);
            this.serverDef = Objects.requireNonNull(serverDef);
        }
    }

    private static class ServerDef
    {
        final IConfigurationElement element;

        ServerDef(IConfigurationElement element)
        {
            this.element = Objects.requireNonNull(element);
        }

        StreamConnectionProvider createStreamConnectionProvider()
            throws CoreException
        {
            return (StreamConnectionProvider)element.createExecutableExtension(
                "class"); //$NON-NLS-1$
        }

        LanguageClient createLanguageClient() throws CoreException
        {
            return (LanguageClient)element.createExecutableExtension(
                "clientImpl"); //$NON-NLS-1$
        }
    }

    private static class ServerKey
    {
        final IProject project;
        final ServerDef serverDef;

        ServerKey(IProject project, ServerDef serverDef)
        {
            this.project = Objects.requireNonNull(project);
            this.serverDef = Objects.requireNonNull(serverDef);
        }

        @Override
        public int hashCode()
        {
            final int prime = 31;
            int result = 1;
            result = prime * result + project.hashCode();
            result = prime * result + serverDef.hashCode();
            return result;
        }

        @Override
        public boolean equals(Object obj)
        {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            ServerKey other = (ServerKey)obj;
            if (!project.equals(other.project))
                return false;
            if (!serverDef.equals(other.serverDef))
                return false;
            return true;
        }
    }
}
