/*******************************************************************************
 * Copyright (c) 2011 itemis AG (http://www.itemis.eu) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *******************************************************************************/
package org.eclipse.osbp.xtext.oxtype.imports;

import static com.google.common.collect.Lists.newArrayList;
import static org.eclipse.xtext.util.Strings.equal;
import static org.eclipse.xtext.util.Strings.isEmpty;

import java.util.List;
import java.util.Map;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.util.ReplaceRegion;
import org.eclipse.xtext.xbase.conversion.XbaseQualifiedNameValueConverter;
import org.eclipse.xtext.xbase.imports.ConflictResolver;
import org.eclipse.xtext.xbase.imports.IUnresolvedTypeResolver;
import org.eclipse.xtext.xbase.imports.NonOverridableTypesProvider;
import org.eclipse.xtext.xbase.imports.RewritableImportSection;
import org.eclipse.xtext.xbase.imports.TypeUsage;
import org.eclipse.xtext.xbase.imports.TypeUsageCollector;
import org.eclipse.xtext.xbase.imports.TypeUsages;

import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Provider;

/**
 * A full copy of xtexts {@link org.eclipse.xtext.xbase.imports.ImportOrganizer}
 * . This class can return the {@link OXTypeRewritableImportSection}.
 */
@SuppressWarnings("restriction")
public class CustomXbaseImportOrganizer {

	@Inject
	private OXTypeRewritableImportSection.Factory importSectionFactory;

	@Inject
	private Provider<JvmTypeEnhancingTypesCollector> typeUsageCollectorProvider;

	@Inject
	private ConflictResolver conflictResolver;

	@Inject
	private NonOverridableTypesProvider nonOverridableTypesProvider;

	@Inject(optional = true)
	private IUnresolvedTypeResolver unresolvedTypeResolver;

	@Inject
	private XbaseQualifiedNameValueConverter nameValueConverter;

	public List<ReplaceRegion> getOrganizedImportChanges(XtextResource resource) {
		TypeUsageCollector typeUsageCollector = typeUsageCollectorProvider
				.get();
		TypeUsages typeUsages = typeUsageCollector.collectTypeUsages(resource);
		if (unresolvedTypeResolver != null)
			unresolvedTypeResolver.resolve(typeUsages, resource);
		Map<String, JvmDeclaredType> name2type = conflictResolver
				.resolveConflicts(typeUsages, nonOverridableTypesProvider,
						resource);
		return getOrganizedImportChanges(resource, name2type, typeUsages);
	}

	private List<ReplaceRegion> getOrganizedImportChanges(
			XtextResource resource,
			Map<String, JvmDeclaredType> resolvedConflicts,
			TypeUsages typeUsages) {
		RewritableImportSection oldImportSection = importSectionFactory
				.parse(resource);

		RewritableImportSection newImportSection = importSectionFactory
				.createNewEmpty(resource);
		addImports(resolvedConflicts, typeUsages, newImportSection);
		List<ReplaceRegion> replaceRegions = getReplacedUsageSites(
				resolvedConflicts, typeUsages, newImportSection);
		for (JvmMember staticImport : typeUsages.getStaticImports()) {
			JvmDeclaredType declaringType = staticImport.getDeclaringType();
			if (oldImportSection.hasStaticImport(declaringType,
					staticImport.getSimpleName(), false)) {
				newImportSection.addStaticImport(staticImport);
			} else {
				newImportSection.addStaticImport(declaringType, null);
			}
		}
		for (JvmMember extensionImport : typeUsages.getExtensionImports()) {
			JvmDeclaredType declaringType = extensionImport.getDeclaringType();
			if (oldImportSection.hasStaticImport(declaringType,
					extensionImport.getSimpleName(), true)) {
				newImportSection.addStaticExtensionImport(extensionImport);
			} else {
				newImportSection.addStaticExtensionImport(declaringType, null);
			}
		}
		replaceRegions.addAll(newImportSection.rewrite());
		return replaceRegions;
	}

	public OXTypeRewritableImportSection getOrganizedImportSection(
			XtextResource resource) {
		TypeUsageCollector typeUsageCollector = typeUsageCollectorProvider
				.get();
		TypeUsages typeUsages = typeUsageCollector.collectTypeUsages(resource);
		if (unresolvedTypeResolver != null)
			unresolvedTypeResolver.resolve(typeUsages, resource);
		Map<String, JvmDeclaredType> name2type = conflictResolver
				.resolveConflicts(typeUsages, nonOverridableTypesProvider,
						resource);
		return getOrganizedImportSection(resource, name2type, typeUsages);
	}

	private OXTypeRewritableImportSection getOrganizedImportSection(
			XtextResource resource,
			Map<String, JvmDeclaredType> resolvedConflicts,
			TypeUsages typeUsages) {
		OXTypeRewritableImportSection oldImportSection = (OXTypeRewritableImportSection) importSectionFactory
				.parse(resource);

		OXTypeRewritableImportSection newImportSection = (OXTypeRewritableImportSection) importSectionFactory
				.createNewEmpty(resource);
		addImports(resolvedConflicts, typeUsages, newImportSection);
		for (JvmMember staticImport : typeUsages.getStaticImports()) {
			JvmDeclaredType declaringType = staticImport.getDeclaringType();
			if (oldImportSection.hasStaticImport(declaringType,
					staticImport.getSimpleName(), false)) {
				newImportSection.addStaticImport(staticImport);
			} else {
				newImportSection.addStaticImport(declaringType, null);
			}
		}
		for (JvmMember extensionImport : typeUsages.getExtensionImports()) {
			JvmDeclaredType declaringType = extensionImport.getDeclaringType();
			if (oldImportSection.hasStaticImport(declaringType,
					extensionImport.getSimpleName(), true)) {
				newImportSection.addStaticExtensionImport(extensionImport);
			} else {
				newImportSection.addStaticExtensionImport(declaringType, null);
			}
		}
		return newImportSection;
	}

	private List<ReplaceRegion> getReplacedUsageSites(
			Map<String, JvmDeclaredType> resolvedConflicts,
			TypeUsages typeUsages, RewritableImportSection newImportSection) {
		List<ReplaceRegion> result = newArrayList();
		for (Map.Entry<String, JvmDeclaredType> textToType : resolvedConflicts
				.entrySet()) {
			getReplacedUsagesOf(textToType, typeUsages, newImportSection,
					result);
		}
		return result;
	}

	private void getReplacedUsagesOf(
			Map.Entry<String, JvmDeclaredType> nameToType,
			TypeUsages typeUsages, RewritableImportSection importSection,
			List<ReplaceRegion> result) {
		String nameToUse = nameToType.getKey();
		JvmDeclaredType type = nameToType.getValue();
		String packageLocalName = getPackageLocalName(type);
		for (TypeUsage typeUsage : typeUsages.getUsages(type)) {
			ReplaceRegion replaceRegion = getReplaceRegion(nameToUse,
					packageLocalName, type, typeUsage, importSection);
			if (replaceRegion != null) {
				result.add(replaceRegion);
			}
		}
	}

	/* @Nullable */
	private ReplaceRegion getReplaceRegion(String nameToUse,
			String packageLocalName, JvmDeclaredType type, TypeUsage usage,
			RewritableImportSection importSection) {
		// if the resource contains two types with the same simple name, we
		// don't add any import
		// but we can still use the package local name within the same package.
		if (equal(usage.getContextPackageName(), type.getPackageName())) {
			if (type.eContainer() != null) {
				String declarationLocalName = getLocalName(type,
						usage.getContext());
				nameToUse = declarationLocalName;
			} else if (importSection.getImportedTypes(packageLocalName) == null) {
				nameToUse = packageLocalName;
			}
		}
		String textToUse = getConcreteSyntax(nameToUse, type, usage);
		return new ReplaceRegion(usage.getTextRegion(), textToUse);
	}

	private String getLocalName(JvmDeclaredType type, JvmMember context) {
		JvmMember containerCandidate = context;
		while (containerCandidate != null) {
			if (containerCandidate == type) {
				return type.getSimpleName();
			} else if (EcoreUtil.isAncestor(containerCandidate, type)) {
				String contextName = containerCandidate.getQualifiedName('.');
				String typeName = type.getQualifiedName('.');
				return typeName.substring(contextName.length() + 1);
			}
			EObject container = containerCandidate.eContainer();
			if (container instanceof JvmMember) {
				containerCandidate = (JvmMember) container;
			} else {
				return null;
			}
		}
		return null;
	}

	private String getConcreteSyntax(String name, JvmDeclaredType importedType,
			TypeUsage usage) {
		JvmDeclaredType usedType = usage.getUsedType();
		if (usedType == null) {
			String typeName = usage.getUsedTypeName();
			String suffix = getSuffix(usage);
			String fullTypeName = typeName + suffix;
			return nameValueConverter.toString(fullTypeName);
		} else {
			if (usedType != importedType) {
				List<String> segments = Lists.newLinkedList();
				while (usedType != importedType) {
					segments.add(0, usedType.getSimpleName());
					usedType = usedType.getDeclaringType();
				}
				name = name + '.' + Joiner.on('.').join(segments);
			} else {
				String suffix = getSuffix(usage);
				name = name + suffix;
			}
			return nameValueConverter.toString(name);
		}
	}

	protected String getSuffix(TypeUsage usage) {
		String suffix = usage.getSuffix();
		suffix = suffix.replace('$', '.').replace("::", ".");
		return suffix;
	}

	private void addImports(Map<String, JvmDeclaredType> resolvedConflicts,
			TypeUsages typeUsages, RewritableImportSection target) {
		for (Map.Entry<String, JvmDeclaredType> entry : resolvedConflicts
				.entrySet()) {
			String text = entry.getKey();
			JvmDeclaredType type = entry.getValue();
			Iterable<TypeUsage> usages = typeUsages.getUsages(type);
			if (needsImport(type, text, nonOverridableTypesProvider, usages)) {
				target.addImport(type);
			}
		}
	}

	protected String getPackageLocalName(JvmDeclaredType type) {
		String packageName = type.getPackageName();
		if (isEmpty(packageName))
			return type.getQualifiedName('.');
		else
			return type.getQualifiedName('.').substring(
					packageName.length() + 1);
	}

	protected boolean needsImport(JvmDeclaredType type, String name,
			NonOverridableTypesProvider nonOverridableTypesProvider,
			Iterable<TypeUsage> usages) {
		boolean nameEquals = type.getQualifiedName().equals(name)
				|| type.getQualifiedName('.').equals(name);
		return !(nameEquals || isUsedInLocalContextOnly(type, usages,
				nonOverridableTypesProvider, name));
	}

	protected boolean isUsedInLocalContextOnly(JvmDeclaredType type,
			Iterable<TypeUsage> usages,
			NonOverridableTypesProvider nonOverridableTypesProvider, String name) {
		for (TypeUsage usage : usages) {
			if (nonOverridableTypesProvider.getVisibleType(usage.getContext(),
					name) == null
					&& !equal(usage.getContextPackageName(),
							type.getPackageName()))
				return false;
		}
		return true;
	}
}
