/******************************************************************************
 * 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.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.lsp4j.jsonrpc.Endpoint;
import org.eclipse.lsp4j.jsonrpc.json.JsonRpcMethod;
import org.eclipse.lsp4j.jsonrpc.json.ResponseJsonAdapter;

import com.google.gson.TypeAdapterFactory;

public final class ServiceEndpoints {
	private ServiceEndpoints() {}
	
	/**
	 * Wraps a given {@link Endpoint} in the given service interface.
	 * 
	 * @return the wrapped service object
	 */
	@SuppressWarnings("unchecked")
	public static <T> T toServiceObject(Endpoint endpoint, Class<T> interface_) {
		Class<?>[] interfArray = new Class[]{interface_, Endpoint.class};
		EndpointProxy invocationHandler = new EndpointProxy(endpoint, interface_);
		return (T) Proxy.newProxyInstance(interface_.getClassLoader(), interfArray, invocationHandler);
	}
	
	/**
	 * Wraps a given {@link Endpoint} in the given service interfaces.
	 * 
	 * @return the wrapped service object
	 */
	public static Object toServiceObject(Endpoint endpoint, Collection<Class<?>> interfaces, ClassLoader classLoader) {
		Class<?>[] interfArray = new Class[interfaces.size() + 1];
		interfaces.toArray(interfArray);
		interfArray[interfArray.length - 1] = Endpoint.class;
		EndpointProxy invocationHandler = new EndpointProxy(endpoint, interfaces);
		return Proxy.newProxyInstance(classLoader, interfArray, invocationHandler);
	}
	
	/**
	 * Wraps a given object with service annotations behind an {@link Endpoint} interface.
	 * 
	 * @return the wrapped service endpoint
	 */
	public static Endpoint toEndpoint(Object serviceObject) {
		return new GenericEndpoint(serviceObject);
	}
	
	/**
	 * Wraps a collection of objects with service annotations behind an {@link Endpoint} interface.
	 * 
	 * @return the wrapped service endpoint
	 */
	public static Endpoint toEndpoint(Collection<Object> serviceObjects) {
		return new GenericEndpoint(serviceObjects);
	}
	
	/**
	 * Finds all Json RPC methods on a given class.
	 * 
	 * @return the supported JsonRpcMethods
	 */
	public static Map<String, JsonRpcMethod> getSupportedMethods(Class<?> type) {
		Set<Class<?>> visitedTypes = new HashSet<>();
		return getSupportedMethods(type, visitedTypes);
	}
	
	/**
	 * Finds all Json RPC methods on a given type
	 */
	private static Map<String, JsonRpcMethod> getSupportedMethods(Class<?> type, Set<Class<?>> visitedTypes) {
		Map<String, JsonRpcMethod> result = new LinkedHashMap<String, JsonRpcMethod>();
		AnnotationUtil.findRpcMethods(type, visitedTypes, (methodInfo) -> {
			JsonRpcMethod meth;
			if (methodInfo.isNotification) {
				meth = JsonRpcMethod.notification(methodInfo.name, methodInfo.parameterTypes);
			} else {
				Type genericReturnType = methodInfo.method.getGenericReturnType();
				if (genericReturnType instanceof ParameterizedType) {
					Type returnType = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0];
					TypeAdapterFactory responseTypeAdapter = null;
					ResponseJsonAdapter responseTypeAdapterAnnotation = methodInfo.method.getAnnotation(ResponseJsonAdapter.class);
					if (responseTypeAdapterAnnotation != null) {
						try {
							responseTypeAdapter = responseTypeAdapterAnnotation.value().newInstance();
						} catch (InstantiationException | IllegalAccessException e) {
							throw new RuntimeException(e);
						}
					}
					meth = JsonRpcMethod.request(methodInfo.name, returnType, responseTypeAdapter, methodInfo.parameterTypes);
				} else {
					throw new IllegalStateException("Expecting return type of CompletableFuture but was : " + genericReturnType);
				}
			}
			if (result.put(methodInfo.name, meth) != null) {
				throw new IllegalStateException("Duplicate RPC method "+methodInfo.name+".");
			};
		});
		
		AnnotationUtil.findDelegateSegments(type, new HashSet<>(), (method)-> {
			Map<String, JsonRpcMethod> supportedDelegateMethods = getSupportedMethods(method.getReturnType(), visitedTypes);
			for (JsonRpcMethod meth : supportedDelegateMethods.values()) {
				if (result.put(meth.getMethodName(), meth) != null) {
					throw new IllegalStateException("Duplicate RPC method "+meth.getMethodName()+".");
				};
			}
		});
		return result;
	}
	
}
