/******************************************************************************
 * Copyright (c) 2016 TypeFox and others.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 * 
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 ******************************************************************************/
package org.eclipse.lsp4j.jsonrpc.services;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;

import org.eclipse.lsp4j.jsonrpc.Endpoint;
import org.eclipse.lsp4j.jsonrpc.ResponseErrorException;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseError;
import org.eclipse.lsp4j.jsonrpc.messages.ResponseErrorCode;

/**
 * An endpoint that reflectively delegates to {@link JsonNotification} and
 * {@link JsonRequest} methods of one or more given delegate objects.
 */
public class GenericEndpoint implements Endpoint {
	
	private static final Logger LOG = Logger.getLogger(GenericEndpoint.class.getName());
	private static final Object[] NO_ARGUMENTS = {};

	private final LinkedHashMap<String, Function<Object, CompletableFuture<Object>>> methodHandlers = new LinkedHashMap<>();
	private final List<Object> delegates;

	public GenericEndpoint(Object delegate) {
		this.delegates = Collections.singletonList(delegate);
		recursiveFindRpcMethods(delegate, new HashSet<>(), new HashSet<>());
	}
	
	public GenericEndpoint(Collection<Object> delegates) {
		this.delegates = new ArrayList<>(delegates);
		for (Object delegate : this.delegates) {
			recursiveFindRpcMethods(delegate, new HashSet<>(), new HashSet<>());
		}
	}

	protected void recursiveFindRpcMethods(Object current, Set<Class<?>> visited, Set<Class<?>> visitedForDelegate) {
		AnnotationUtil.findRpcMethods(current.getClass(), visited, (methodInfo) -> {
			@SuppressWarnings("unchecked")
			Function<Object, CompletableFuture<Object>> handler = (arg) -> {
				try {
					Method method = methodInfo.method;
					Object[] arguments = this.getArguments(method, arg);
					return (CompletableFuture<Object>) method.invoke(current, arguments);
				} catch (InvocationTargetException | IllegalAccessException e) {
					throw new RuntimeException(e);
				}
			};
			if (methodHandlers.put(methodInfo.name, handler) != null) {
				throw new IllegalStateException("Multiple methods for name " + methodInfo.name);
			}
		});
		AnnotationUtil.findDelegateSegments(current.getClass(), visitedForDelegate, (method) -> {
			try {
				Object delegate = method.invoke(current);
				if (delegate != null) {
					recursiveFindRpcMethods(delegate, visited, visitedForDelegate);
				} else {
					LOG.log(Level.SEVERE, "A delegate object is null, jsonrpc methods of '" + method + "' are ignored");
				}
			} catch (InvocationTargetException | IllegalAccessException e) {
				throw new RuntimeException(e);
			}
		});
	}
	
	protected Object[] getArguments(Method method, Object arg) {
		int parameterCount = method.getParameterCount();
		if (parameterCount == 0) {
			if (arg != null) {
				LOG.warning("Unexpected params '" + arg + "' for '" + method + "' is ignored");
			}
			return NO_ARGUMENTS;
		}
		if (arg instanceof List<?>) {
			List<?> arguments = (List<?>) arg;
			int argumentCount = arguments.size(); 
			if (argumentCount == parameterCount) {
				return arguments.toArray();
			}
			if (argumentCount > parameterCount) {
				Stream<?> unexpectedArguments = arguments.stream().skip(parameterCount);
				String unexpectedParams = unexpectedArguments.map(a -> "'" + a + "'").reduce((a, a2) -> a + ", " + a2).get();
				LOG.warning("Unexpected params " + unexpectedParams + " for '" + method + "' is ignored");
				return arguments.subList(0, parameterCount).toArray();
			}
			return arguments.toArray(new Object[parameterCount]);
		}
		Object[] arguments = new Object[parameterCount];
		arguments[0] = arg;
		return arguments;
	}

	@Override
	public CompletableFuture<?> request(String method, Object parameter) {
		// Check the registered method handlers
		Function<Object, CompletableFuture<Object>> handler = methodHandlers.get(method);
		if (handler != null) {
			return handler.apply(parameter);
		}
		
		// Ask the delegate objects whether they can handle the request generically
		List<CompletableFuture<?>> futures = new ArrayList<>(delegates.size());
		for (Object delegate : delegates) {
			if (delegate instanceof Endpoint) {
				futures.add(((Endpoint) delegate).request(method, parameter));
			}
		}
		if (!futures.isEmpty()) {
			return CompletableFuture.anyOf(futures.toArray(new CompletableFuture[futures.size()]));
		}
		
		// Create a log message about the unsupported method
		String message = "Unsupported request method: " + method;
		if (isOptionalMethod(method)) {
			LOG.log(Level.INFO, message);
			return CompletableFuture.completedFuture(null);
		}
		LOG.log(Level.WARNING, message);
		CompletableFuture<?> exceptionalResult = new CompletableFuture<Object>();
		ResponseError error = new ResponseError(ResponseErrorCode.MethodNotFound, message, null);
		exceptionalResult.completeExceptionally(new ResponseErrorException(error));
		return exceptionalResult;
	}

	@Override
	public void notify(String method, Object parameter) {
		// Check the registered method handlers
		Function<Object, CompletableFuture<Object>> handler = methodHandlers.get(method);
		if (handler != null) {
			handler.apply(parameter);
			return;
		}
		
		// Ask the delegate objects whether they can handle the notification generically
		int notifiedDelegates = 0;
		for (Object delegate : delegates) {
			if (delegate instanceof Endpoint) {
				((Endpoint) delegate).notify(method, parameter);
				notifiedDelegates++;
			}
		}
		
		if (notifiedDelegates == 0) {
			// Create a log message about the unsupported method
			String message = "Unsupported notification method: " + method;
			if (isOptionalMethod(method)) {
				LOG.log(Level.INFO, message);
			} else {
				LOG.log(Level.WARNING, message);
			}
		}
	}
	
	protected boolean isOptionalMethod(String method) {
		return method != null && method.startsWith("$/");
	}

}
