/*******************************************************************************
 * Copyright (c) 2013, 2020 CEA LIST and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *   E.D.Willink(CEA LIST) - Initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.examples.codegen.utilities;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGClass;
import org.eclipse.ocl.examples.codegen.cgmodel.CGConstantExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGConstraint;
import org.eclipse.ocl.examples.codegen.cgmodel.CGElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGExecutorType;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterator;
import org.eclipse.ocl.examples.codegen.cgmodel.CGLetExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGModelFactory;
import org.eclipse.ocl.examples.codegen.cgmodel.CGParameter;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTupleExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTuplePart;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTypeId;
import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGVariable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGVariableExp;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.ids.ElementId;
import org.eclipse.ocl.pivot.ids.OclVoidTypeId;
import org.eclipse.ocl.pivot.ids.PrimitiveTypeId;
import org.eclipse.ocl.pivot.ids.TemplateParameterId;
import org.eclipse.ocl.pivot.utilities.ClassUtil;

public class CGUtil
{
	/**
	 * Simplify org.eclipse.jdt.annotation references that unnecessarily use long firm within a long firm.
	 * e.g. replace
	 *
	 * "X.Y.@org.eclipse.jdt.annotation.NonNull Z" by "@NonNull Z" if "X.Y.Z" is an import.
	 * "java.lang.@org.eclipse.jdt.annotation.NonNull Z" by "@NonNull Z".
	 * "Y.@org.eclipse.jdt.annotation.NonNull Z" by "Y.@NonNull Z"
	 */
	public static @NonNull String compressJDTannotations(@NonNull String classFileContent) {
		final String ORG_ECLIPSE_JDT_ANNOTATION = org.eclipse.jdt.annotation.NonNull.class.getPackage().getName();
		final String AT_ORG_ECLIPSE_JDT_ANNOTATION_DOT = "@" + ORG_ECLIPSE_JDT_ANNOTATION + ".";
		Set<@NonNull String> reservedNames = new HashSet<>();
		reservedNames.add("Byte");
		reservedNames.add("Character");
		reservedNames.add("Class");
		reservedNames.add("Double");
		reservedNames.add("Enum");
		reservedNames.add("Error");
		reservedNames.add("Exception");
		reservedNames.add("Float");
		reservedNames.add("Integer");
		reservedNames.add("Long");
		reservedNames.add("Math");
		reservedNames.add("Object");
		reservedNames.add("Package");
		reservedNames.add("Process");
		reservedNames.add("Short");
		reservedNames.add("String");
		try {
			Set<@NonNull String> longImports = new HashSet<>();
			BufferedReader reader = new BufferedReader(new StringReader(classFileContent));
			StringBuilder s = new StringBuilder();
			for (String line; (line = reader.readLine()) != null; ) {
				if (line.startsWith("import ")) {
					int index = line.indexOf(";");
					if (index > 0) {
						String longImport = line.substring(7, index).trim();
						int lastIndex = longImport.lastIndexOf(".");
						if (lastIndex > 0) {
							String shortImport = longImport.substring(lastIndex+1);
							assert shortImport != null;
							if (!reservedNames.contains(shortImport)) {
								longImports.add(longImport);
							}
							//							String oldLongImport = shortImports.put(shortImport, longImport);
							//							if (oldLongImport != null) {
							//								shortImports.put(shortImport, shortImport);
							//							}
						}
					}
				}
				while (true) {
					int prefixEnd = line.indexOf(AT_ORG_ECLIPSE_JDT_ANNOTATION_DOT);
					if (prefixEnd < 0) {
						break;
					}
					int prefixIndex = prefixEnd;
					for (; prefixIndex > 0; --prefixIndex) {
						char c = line.charAt(prefixIndex-1);
						if ((c != '.') && !Character.isJavaIdentifierPart(c)) {
							break;
						}
					}
					String prefixName = line.substring(prefixIndex, prefixEnd-1);
					int annotationStart = prefixEnd + AT_ORG_ECLIPSE_JDT_ANNOTATION_DOT.length();
					int annotationEnd = annotationStart+1;
					for (; true; ++annotationEnd) {
						char c = line.charAt(annotationEnd);
						if (!Character.isJavaIdentifierPart(c)) {
							break;
						}
					}
					String annotationName = line.substring(annotationStart, annotationEnd);
					if (!longImports.contains(ORG_ECLIPSE_JDT_ANNOTATION + "." + annotationName)) {
						break;
					}
					int suffixStart = annotationEnd;
					for (; true; ++suffixStart) {
						char c = line.charAt(suffixStart);
						if (!Character.isWhitespace(c)) {
							break;
						}
					}
					int suffixEnd = suffixStart;
					for (; true; ++suffixEnd) {
						char c = line.charAt(suffixEnd);
						if (!Character.isJavaIdentifierPart(c)) {
							break;
						}
					}
					String suffixName = line.substring(suffixStart, suffixEnd);
					String importName = prefixName + "." + suffixName;
					if (longImports.contains(importName) || importName.startsWith("java.lang.")) {
						line = line.substring(0, prefixIndex) + "@" + line.substring(annotationStart, line.length());
					}
					else {
						line = line.substring(0, prefixEnd) + "@" + line.substring(annotationStart, line.length());
						break;
					}
				}
				//				if (!line.startsWith("import org.eclipse.ocl.pivot.Class;") && !line.startsWith("import org.eclipse.ocl.pivot.Package;")) {
				s.append(line);
				s.append("\n");
				//				}
			}
			return s.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return classFileContent;
	}

	public static @NonNull CGParameter createCGParameter(@NonNull String name, @NonNull CGTypeId typeId) {
		CGParameter cgParameter = CGModelFactory.eINSTANCE.createCGParameter();
		cgParameter.setName(name);
		cgParameter.setTypeId(typeId);
		return cgParameter;
	}

	public static @NonNull OCLExpression getAST(@NonNull CGCallExp cgCallExp) {
		return ClassUtil.nonNullState((OCLExpression)cgCallExp.getAst());
	}

	public static org.eclipse.ocl.pivot.@NonNull Class getAST(@NonNull CGClass cgClass) {
		return ClassUtil.nonNullState((org.eclipse.ocl.pivot.Class)cgClass.getAst());
	}

	public static @NonNull Constraint getAST(@NonNull CGConstraint cgConstraint) {
		return ClassUtil.nonNullState((Constraint)cgConstraint.getAst());
	}

	public static @NonNull Variable getAST(@NonNull CGIterator cgIterator) {
		return ClassUtil.nonNullState((Variable)cgIterator.getAst());
	}

	public static @NonNull /*ParameterVariable*/ VariableDeclaration getAST(@NonNull CGParameter cgParameter) {
		return ClassUtil.nonNullState((VariableDeclaration)cgParameter.getAst());
	}

	public static @NonNull List<@NonNull CGIterator> getCoIteratorsList(@NonNull CGIterationCallExp cgIterationCallExp) {
		return ClassUtil.nullFree(cgIterationCallExp.getCoIterators());
	}

	public static @Nullable CGClass getContainingClass(@NonNull CGElement cgExpression) {
		for (CGElement cgElement = cgExpression; cgElement != null; cgElement = cgElement.getParent()) {
			if (cgElement instanceof CGClass) {
				return (CGClass) cgElement;
			}
		}
		return null;
	}

	public static @Nullable CGConstraint getContainingConstraint(@NonNull CGElement cgExpression) {
		for (CGElement cgElement = cgExpression; cgElement != null; cgElement = cgElement.getParent()) {
			if (cgElement instanceof CGConstraint) {
				return (CGConstraint) cgElement;
			}
		}
		return null;
	}

	/*	public static @Nullable CGOperation getContainingOperation(@NonNull CGValuedElement cgExpression) {
		for (CGElement cgElement = cgExpression; cgElement != null; cgElement = cgElement.getParent()) {
			if (cgElement instanceof CGOperation) {
				return (CGOperation) cgElement;
			}
		}
		return null;
	} */

	public static @NonNull CGValuedElement getIn(@NonNull CGLetExp cgLetExp) {
		return ClassUtil.nonNullState(cgLetExp.getIn());
	}

	public static @NonNull CGValuedElement getInit(@NonNull CGTuplePart cgTuplePart) {
		return ClassUtil.nonNullState(cgTuplePart.getInit());
	}

	public static @NonNull CGValuedElement getInit(@NonNull CGVariable cgVariable) {
		return ClassUtil.nonNullState(cgVariable.getInit());
	}

	public static @NonNull List<@NonNull CGIterator> getIteratorsList(@NonNull CGIterationCallExp cgIterationCallExp) {
		return ClassUtil.nullFree(cgIterationCallExp.getIterators());
	}

	public static Iterable<@NonNull CGTuplePart> getParts(@NonNull CGTupleExp cgTupleExp) {
		return ClassUtil.nullFree(cgTupleExp.getParts());
	}

	public static @NonNull CGValuedElement getReferredConstant(@NonNull CGConstantExp cgConstantExp) {
		return ClassUtil.nonNullState(cgConstantExp.getReferredConstant());
	}

	public static @NonNull CGValuedElement getReferredVariable(@NonNull CGVariableExp cgVariableExp) {
		return ClassUtil.nonNullState(cgVariableExp.getReferredVariable());
	}

	public static boolean isInlinedId(@NonNull ElementId elementId) {
		return (elementId instanceof PrimitiveTypeId)
				|| (elementId instanceof OclVoidTypeId)
				|| (elementId instanceof TemplateParameterId);
	}

	public static @Nullable Boolean isKindOf(@NonNull CGValuedElement cgValue, @NonNull CGExecutorType executorType) {
		CGTypeId referenceTypeId = executorType.getUnderlyingTypeId();
		CGTypeId actualTypeId = cgValue.getTypeId();
		return referenceTypeId == actualTypeId ? Boolean.TRUE : null;			// FIXME support conformance somehow
	}

	/**
	 * Return true if the testNameSuffix system property has been set to indicate tests are
	 * running under the supervision of the maven-surefire-plugin..
	 */
	public static boolean isMavenSurefire() {
		String testNameSuffix = System.getProperty("testNameSuffix", "");
		return (testNameSuffix != null) && testNameSuffix.startsWith("maven");
	}

	/**
	 * Return true if the testNameSuffix system property has been set to indicate tests are
	 * running under the supervision of the tycho-surefire-plugin..
	 */
	public static boolean isTychoSurefire() {
		String testNameSuffix = System.getProperty("testNameSuffix", "");
		return (testNameSuffix != null) && testNameSuffix.startsWith("tycho");
	}

	/**
	 * Replace oldElement by newElement and return oldElement which is orphaned by the replacement.
	 */
	public static @NonNull CGValuedElement replace(@NonNull CGValuedElement oldElement, @NonNull CGValuedElement newElement) {
		assert !oldElement.isRequired() || !newElement.isNull();
		EObject oldContainer = oldElement.eContainer();
		//		EObject newContainer = newElement.eContainer();
		//		assert (oldContainer != null) && (newContainer == null);
		EcoreUtil.replace(oldElement, newElement);
		assert oldElement.eContainer() == null;
		assert newElement.eContainer() == oldContainer;
		return oldElement;
	}

	/**
	 * Trim trailing spaces from lines.
	 */
	public static @NonNull String trimLines(@NonNull String classFileContent) {
		try {
			BufferedReader reader = new BufferedReader(new StringReader(classFileContent));
			StringBuilder s = new StringBuilder();
			for (String line; (line = reader.readLine()) != null; ) {
				int len = line.length();
				int i = len;
				while ((i > 0) && Character.isWhitespace(line.charAt(i-1))) {
					i--;
				}
				s.append(i < len ? line.substring(0, i) : line);
				s.append("\n");
			}
			return s.toString();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return classFileContent;
	}

	/**
	 * Use wrapExp to wrap wrappedExp.
	 */
	public static void wrap(@NonNull CGCallExp wrapExp, @NonNull CGValuedElement wrappedExp) {
		wrapExp.setTypeId(wrappedExp.getTypeId());
		wrapExp.setAst(wrappedExp.getAst());
		replace(wrappedExp, wrapExp);
		wrapExp.setSource(wrappedExp);
	}
}
