/*******************************************************************************
 * Copyright (c) 2015 Obeo.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Obeo - initial API and implementation
 *******************************************************************************/
package org.eclipse.acceleo.query.services;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.acceleo.annotations.api.documentation.Documentation;
import org.eclipse.acceleo.annotations.api.documentation.Example;
import org.eclipse.acceleo.annotations.api.documentation.Other;
import org.eclipse.acceleo.annotations.api.documentation.Param;
import org.eclipse.acceleo.annotations.api.documentation.ServiceProvider;
import org.eclipse.acceleo.query.ast.Call;
import org.eclipse.acceleo.query.runtime.IReadOnlyQueryEnvironment;
import org.eclipse.acceleo.query.runtime.IService;
import org.eclipse.acceleo.query.runtime.IValidationResult;
import org.eclipse.acceleo.query.runtime.impl.AbstractServiceProvider;
import org.eclipse.acceleo.query.runtime.impl.JavaMethodService;
import org.eclipse.acceleo.query.runtime.impl.Nothing;
import org.eclipse.acceleo.query.runtime.impl.ValidationServices;
import org.eclipse.acceleo.query.validation.type.ClassType;
import org.eclipse.acceleo.query.validation.type.EClassifierType;
import org.eclipse.acceleo.query.validation.type.IType;
import org.eclipse.emf.common.util.Enumerator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EEnum;
import org.eclipse.emf.ecore.EEnumLiteral;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;

//@formatter:off
@ServiceProvider(
	value = "Services available for all types"
)
//@formatter:on
@SuppressWarnings({"checkstyle:javadocmethod", "checkstyle:javadoctype" })
public class AnyServices extends AbstractServiceProvider {

	/**
	 * Line separator constant.
	 */
	private static final String LINE_SEP = System.getProperty("line.separator");

	/**
	 * The {@link IReadOnlyQueryEnvironment}.
	 */
	private final IReadOnlyQueryEnvironment queryEnvironment;

	/**
	 * Constructor.
	 * 
	 * @param queryEnvironment
	 *            the {@link IReadOnlyQueryEnvironment}
	 */
	public AnyServices(IReadOnlyQueryEnvironment queryEnvironment) {
		this.queryEnvironment = queryEnvironment;
	}

	@Override
	protected IService getService(Method publicMethod) {
		final IService result;

		if ("oclAsType".equals(publicMethod.getName())) {
			result = new OCLAsTypeService(publicMethod, this);
		} else {
			result = new JavaMethodService(publicMethod, this);
		}

		return result;
	}

	// @formatter:off
	@Documentation(
		value = "Indicates whether the object \"o1\" i\"the same as the object \"o2\". For more " +
	            "information refer to the Object#equals(Object) method.",
	    params = {
			@Param(name = "o1", value = "The object to compare for equality"),
			@Param(name = "o2", value = "The reference object with which to compare")
		},
		result = "true\" if the object \"o1\" is the same as the object \"o2\", " +
		         "\"false\" otherwise",
		examples = {
			@Example(expression = "'Hello'.equals('World')", result = "false"),
			@Example(expression = "'Hello'.equals('Hello')", result = "true")
		}
	)
	// @formatter:on
	public Boolean equals(Object o1, Object o2) {
		final boolean result;

		if (o1 == null) {
			result = o2 == null;
		} else {
			result = o1.equals(o2);
		}

		return Boolean.valueOf(result);
	}

	// @formatter:off
	@Documentation(
		value = "Indicates whether the object \"o1\" is a different object from the object \"o2\".",
		params = {
			@Param(name = "o1", value = "The object to compare"),
			@Param(name = "o2", value = "The reference object with which to compare")
		},
		result = "\"true\" if the object \"o1\" is not the same as the object \"o2\", " +
				 "\"false\" otherwise.",
		examples = {
			@Example(expression = "'Hello'.differs('World')", result = "true"),
			@Example(expression = "'Hello'.differs('Hello')", result = "false")
		}
	)
	// @formatter:on
	public Boolean differs(Object o1, Object o2) {
		return Boolean.valueOf(!equals(o1, o2));
	}

	// @formatter:off
	@Documentation(
		value = "Returns the concatenation of self (as a String) and the given string \"s\".",
		params = {
			@Param(name = "self", value = "The current object at the end of which to append \"s\"."),
			@Param(name = "s", value = "The string we want to append at the end of the current object's string representation.")
		},
		result = "The string representation of self for which we added the string \"s\".",
		examples = {
			@Example(expression = "42.add(' times')", result = "'42 times'")
		}
	)
	// @formatter:on
	public String add(Object self, String s) {
		final String result;

		if (s == null) {
			result = toString(self);
		} else {
			result = toString(self) + s;
		}

		return result;
	}

	// @formatter:off
	@Documentation(
		value = "Returns the concatenation of the current string and the given object \"any\" (as a String).",
		params = {
			@Param(name = "self", value = "The current string."),
			@Param(name = "any", value = "The object we want to append, as a string, at the end of the current string.")
		},
		result = "The current string with the object \"any\" appended (as a String).",
		examples = {
			@Example(expression = "'times '.add(42)", result = "'times 42'")
		}
	)
	// @formatter:on
	public String add(String self, Object any) {
		final String result;

		if (self == null) {
			result = toString(any);
		} else {
			result = self + toString(any);
		}

		return result;
	}

	// @formatter:off
	@Documentation(
		value = "Casts the current object to the given type.",
		params = {
			@Param(name = "object", value = "The object to cast"),
			@Param(name = "type", value = "The type to cast the object to")
		},
		result = "The current object cast to a \"type\"",
		examples = {
			@Example(
				expression = "anEPackage.oclAsType(ecore::EPackage)", result = "anEPackage",
				others = {
					@Other(
						language = Other.ACCELEO_3, expression = "anEPackage.oclAsType(ecore::EPackage)", result = "anEPackage"
					)
				}
			),
			@Example(
				expression = "anEPackage.oclAsType(ecore::EClass)", result = "anEPackage",
				others = {
					@Other(
						language = Other.ACCELEO_3, expression = "anEPackage.oclAsType(ecore::EClass)", result = "oclInvalid"
					)
				}
			),
		},
		comment = "Contrary to Acceleo 3, the type is ignored, the given object will be returned directly."
	)
	// @formatter:on
	public Object oclAsType(Object object, Object type) {
		if (oclIsKindOf(object, type)) {
			return object;
		}
		throw new ClassCastException(object + " cannot be cast to " + type);
	}

	// @formatter:off
	@Documentation(
		value = "Evaluates to \"true\" if the type of the object o1 conforms to the type \"classifier\". That is, " +
				"o1 is of type \"classifier\" or a subtype of \"classifier\".",
		params = {
			@Param(name = "object", value = "The reference Object we seek to test."),
			@Param(name = "type", value = "The expected supertype classifier.")
		},
		result = "\"true\" if the object o1 is a kind of the classifier, \"false\" otherwise.",
		examples = {
			@Example(expression = "anEPackage.oclIsKindOf(ecore::EPackage)", result = "true"),
			@Example(expression = "anEPackage.oclIsKindOf(ecore::ENamedElement)", result = "true")
		}
	)
	// @formatter:on
	public Boolean oclIsKindOf(Object object, Object type) {
		Boolean result;
		if (object == null && type != null) {
			// OCL considers "null" (OclVoid) to be compatible with everything.
			// AQL considers it incompatible with anything.
			result = false;
		} else if (type instanceof EClass) {
			EClass eClass = (EClass)type;
			if (object instanceof EObject) {
				result = eClass.isInstance(object);
			} else {
				result = false;
			}
		} else if (type instanceof EEnum) {
			if (object instanceof EEnumLiteral) {
				result = ((EEnumLiteral)object).getEEnum().equals(type);
			} else if (object instanceof Enumerator) {
				EEnumLiteral literal = ((EEnum)type).getEEnumLiteral(((Enumerator)object).getName());
				result = literal.getEEnum().equals(type);
			} else {
				result = false;
			}
		} else if (type instanceof EDataType) {
			result = ((EDataType)type).isInstance(object);
		} else if (object != null && type instanceof Class<?>) {
			result = ((Class<?>)type).isInstance(object);
		} else {
			result = false;
		}
		return result;
	}

	// @formatter:off
	@Documentation(
		value = "Evaluates to \"true\" if the object o1 if of the type \"classifier\" but not a subtype of the " +
				"\"classifier\".",
		params = {
			@Param(name = "object", value = "The reference Object we seek to test."),
			@Param(name = "type", value = "The expected type classifier.")
		},
		result = "\"true\" if the object o1 is a type of the classifier, \"false\" otherwise.",
		examples = {
			@Example(expression = "anEPackage.oclIsKindOf(ecore::EPackage)", result = "true"),
			@Example(expression = "anEPackage.oclIsKindOf(ecore::ENamedElement)", result = "false")
		}
	)
	// @formatter:on
	public Boolean oclIsTypeOf(Object object, Object type) {
		Boolean result;
		if (object == null && type != null) {
			// OCL considers "null" (OclVoid) to be compatible with everything.
			// AQL considers it incompatible with anything.
			result = false;
		} else if (type instanceof EClass) {
			EClass eClass = (EClass)type;
			if (object instanceof EObject) {
				result = eClass == ((EObject)object).eClass();
			} else {
				result = false;
			}
		} else if (type instanceof EEnum) {
			if (object instanceof EEnumLiteral) {
				result = ((EEnumLiteral)object).getEEnum().equals(type);
			} else if (object instanceof Enumerator) {
				EEnumLiteral literal = ((EEnum)type).getEEnumLiteral(((Enumerator)object).getName());
				result = literal.getEEnum().equals(type);
			} else {
				result = false;
			}
		} else if (type instanceof EDataType) {
			result = ((EDataType)type).isInstance(object);
		} else if (object != null && type instanceof Class<?>) {
			result = ((Class<?>)type).equals(object.getClass());
		} else {
			result = false;
		}
		return result;
	}

	// @formatter:off
	@Documentation(
		value = "Returns a string representation of the current object.",
		params = {
			@Param(name = "self", value = "The current object")
		},
		result = "a String representation of the given Object. For Collections, this will be the concatenation of " +
				 "all contained Objects' toString.",
		examples = {
			@Example(expression = "42.toString()", result = "'42'")
		}
	)
	// @formatter:on
	public String toString(Object object) {
		final StringBuffer buffer = new StringBuffer();
		if (object instanceof Collection<?>) {
			final Iterator<?> childrenIterator = ((Collection<?>)object).iterator();
			while (childrenIterator.hasNext()) {
				buffer.append(toString(childrenIterator.next()));
			}
		} else if (object != null && !(object instanceof Nothing)) {
			final String toString = object.toString();
			if (toString != null) {
				buffer.append(toString);
			}
		}
		// else return empty String
		return buffer.toString();
	}

	// @formatter:off
	@Documentation(
		value = "Returns a string representation of the current environment.",
		params = {
			@Param(name = "self", value = "The current object")
		},
		result = "a string representation of the current environment.",
		examples = {
			@Example(expression = "42.trace()", result = "'Metamodels:\n\thttp://www.eclipse.org/emf/2002/Ecore\n" +
					"Services:\n\torg.eclipse.acceleo.query.services.AnyServices\n\t\tpublic java.lang.String org." +
					"eclipse.acceleo.query.services.AnyServices.add(java.lang.Object,java.lang.String)\n\t\t...\nreceiver: 42\n'")
		}
	)
	// @formatter:on
	public String trace(Object object) {
		final StringBuilder result = new StringBuilder();

		result.append("Metamodels:" + LINE_SEP);
		for (EPackage ePgk : queryEnvironment.getEPackageProvider().getRegisteredEPackages()) {
			result.append("\t" + ePgk.getNsURI() + LINE_SEP);
		}
		result.append("Services:" + LINE_SEP);
		final List<IService> services = new ArrayList<IService>(queryEnvironment.getLookupEngine()
				.getRegisteredServices());
		Collections.sort(services, new Comparator<IService>() {

			/**
			 * {@inheritDoc}
			 *
			 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
			 */
			@Override
			public int compare(IService service1, IService service2) {
				final int result;

				if (service1.getPriority() < service2.getPriority()) {
					result = -1;
				} else if (service1.getPriority() < service2.getPriority()) {
					result = 1;
				} else {
					result = service1.getName().compareTo(service2.getName());
				}
				return result;
			}

		});
		for (IService service : services) {
			result.append("\t\t" + service.getLongSignature() + LINE_SEP);
		}
		result.append("receiver: ");
		result.append(toString(object) + LINE_SEP);

		return result.toString();
	}

	private static class OCLAsTypeService extends FilterService {
		public OCLAsTypeService(Method publicMethod, Object serviceInstance) {
			super(publicMethod, serviceInstance);
		}

		@Override
		public Set<IType> getType(Call call, ValidationServices services, IValidationResult validationResult,
				IReadOnlyQueryEnvironment environment, List<IType> argTypes) {
			final Set<IType> result = new LinkedHashSet<IType>();

			final IType receiverType = argTypes.get(0);
			final IType filterType = argTypes.get(1);
			if (services.lower(receiverType, filterType) != null) {
				Object resultType = filterType.getType();
				if (resultType instanceof EClassifier) {
					result.add(new EClassifierType(environment, (EClassifier)resultType));
				} else if (resultType instanceof Class) {
					result.add(new ClassType(environment, (Class<?>)resultType));
				} else if (resultType != null) {
					result.add(services.nothing("Unknown type %s", resultType));
				} else {
					result.add(services.nothing("Unknown type %s", "null"));
				}
			} else {
				if (receiverType instanceof EClassifierType
						&& !environment.getEPackageProvider().isRegistered(
								((EClassifierType)receiverType).getType())) {
					result.add(services.nothing("%s is not registered within the current environment.",
							receiverType));
				} else if (filterType instanceof EClassifierType
						&& !environment.getEPackageProvider().isRegistered(
								((EClassifierType)filterType).getType())) {
					result.add(services.nothing("%s is not registered within the current environment.",
							filterType));
				} else {
					result.add(services.nothing("%s is not compatible with %s", receiverType, filterType));
				}
			}

			return result;
		}
	}
}
