/*******************************************************************************
 * Copyright (c) 2009, 2010 IBM Corporation and others.
 *
 * 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
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ccvs.core;

import java.util.*;

import org.eclipse.core.resources.IProject;
import org.eclipse.team.internal.ccvs.core.CVSProjectSetCapability.LoadInfo;
import org.eclipse.team.internal.ccvs.core.util.KnownRepositories;

public class CVSRepositoryLocationMatcher {

	private static final String EXTSSH = "extssh"; //$NON-NLS-1$
	private static final String PSERVER = "pserver"; //$NON-NLS-1$
	private static final String EXT = "ext"; //$NON-NLS-1$

	private static Comparator COMPATIBLE_LOCATIONS_COMPARATOR = (o1, o2) -> {
		if (o1 instanceof ICVSRepositoryLocation
				&& o2 instanceof ICVSRepositoryLocation) {
			ICVSRepositoryLocation rl1 = (ICVSRepositoryLocation) o1;
			ICVSRepositoryLocation rl2 = (ICVSRepositoryLocation) o2;
			String name1 = rl1.getMethod().getName();
			String name2 = rl2.getMethod().getName();

			if (!name1.equals(name2) && isCompatible(rl1, rl2, false)) {
				if (name1.equals(EXTSSH))
					return -1;
				if (name2.equals(EXTSSH))
					return 1;
				if (name1.equals(PSERVER))
					return -1;
				if (name2.equals(PSERVER))
					return 1;
				if (name1.equals(EXT))
					return -1;
				if (name2.equals(EXT))
					return 1;
			}
			return name1.compareTo(name2);
		}
		return 0;
	};

	public static Map<IProject, List<ICVSRepositoryLocation>> prepareSuggestedRepositoryLocations(
			IProject[] projects, final Map<IProject, LoadInfo> infoMap) {
		List<IProject> confirmedProjectsList = Arrays.asList(projects);
		Set<ICVSRepositoryLocation> projectSetRepositoryLocations = new HashSet<>();
		for (Iterator i = infoMap.keySet().iterator(); i.hasNext();) {
			IProject project = (IProject) i.next();
			if (confirmedProjectsList.contains(project)) {
				LoadInfo loadInfo = (LoadInfo) infoMap.get(project);
				projectSetRepositoryLocations.add(loadInfo.repositoryLocation);
			}
		}

		// none of projects from project sets is confirmed to overwrite
		if (projectSetRepositoryLocations.isEmpty()) {
			return null;
		}

		List<ICVSRepositoryLocation> knownRepositories = Arrays
				.asList(KnownRepositories.getInstance().getRepositories());

		if (knownRepositories.isEmpty()) {
			// There are no known repositories so use repository location from
			// the project set.
			Map result = new HashMap();
			for (Iterator i = projectSetRepositoryLocations.iterator(); i
					.hasNext();) {
				ICVSRepositoryLocation projectSetRepositoryLocation = (ICVSRepositoryLocation) i
						.next();
				ArrayList<ICVSRepositoryLocation> list = new ArrayList<>(1);
				list.add(projectSetRepositoryLocation);
				result.put(projectSetRepositoryLocation, list);
			}
			return result;
		} else if (knownRepositories.containsAll(projectSetRepositoryLocations)) {
			// All repositories are known, no need to prompt for additional
			// information.
			return Collections.emptyMap();
		} else {
			// Not all repositories from the project set are known.
			Map result = new HashMap();

			for (Iterator i = projectSetRepositoryLocations.iterator(); i
					.hasNext();) {
				ICVSRepositoryLocation projectSetRepositoryLocation = (ICVSRepositoryLocation) i
						.next();

				List matching = new ArrayList();
				List compatible = new ArrayList();
				List list = new ArrayList();
				for (Iterator j = knownRepositories.iterator(); j.hasNext();) {
					ICVSRepositoryLocation knownRepositoryLocation = (ICVSRepositoryLocation) j
							.next();
					// There can be more than one perfect match (i.e. two
					// known, matching repositories with different user names)
					if (CVSRepositoryLocationMatcher.isMatching(
							projectSetRepositoryLocation,
							knownRepositoryLocation)) {
						matching.add(knownRepositoryLocation);
					} else if (CVSRepositoryLocationMatcher.isCompatible(
							knownRepositoryLocation,
							projectSetRepositoryLocation, false)) {
						compatible.add(knownRepositoryLocation);
					} else {
						list.add(knownRepositoryLocation);
					}
				}

				// Sort compatible repository locations starting from extssh,
				// followed by pserver and finally ext.
				Collections.sort(compatible, COMPATIBLE_LOCATIONS_COMPARATOR);

				// Add compatible repos before others
				list.addAll(0, compatible);

				if (matching.isEmpty()) {
					// If no matching repo locations found add the one
					// from the project set first.
					list.add(0, projectSetRepositoryLocation);
				} else if (matching.size() == 1) {
					// There is only one matching, known repository
					// so there is no need to ask for any additional info.
					// Don't add it to the 'resultMap'
					list.clear();
					list.addAll(matching);
					result.put(projectSetRepositoryLocation, list);
					continue;
				} else {
					// There is more than one matching, known repository, so
					// ask which one we should use during the import
					list.addAll(0, matching);
				}

				result.put(projectSetRepositoryLocation, list);
			}
			return result;
		}
	}

	/**
	 * Same check as in
	 * org.eclipse.team.internal.ccvs.ui.CVSProjectPropertiesPage class.
	 * 
	 * @see org.eclipse.team.internal.ccvs.ui.CVSProjectPropertiesPage#isCompatible
	 * 
	 * @param location1
	 *            First repository location to match
	 * @param location2
	 *            Second repository location to match
	 * @param equalIsCompatible
	 *            If equal means compatible
	 * @return <code>true</code> if given repository location are compatible,
	 *         otherwise <code>false</code> is returned.
	 */
	public static boolean isCompatible(ICVSRepositoryLocation location1,
			ICVSRepositoryLocation location2, boolean equalIsCompatible) {
		if (!location1.getHost().equals(location2.getHost()))
			return false;
		if (!location1.getRootDirectory().equals(location2.getRootDirectory()))
			return false;
		if (!equalIsCompatible && location1.equals(location2))
			return false;
		return true;
	}

	/**
	 * Checks whether two repository locations match (i.e. they are compatible,
	 * they use the same connection method and they use the same port) .
	 * 
	 * @param location1
	 *            First repository location to match
	 * @param location2
	 *            Second repository location to match
	 * @return <code>true</code> if given repository location are matching
	 *         according to the rule above, otherwise <code>false</code> is
	 *         returned.
	 */
	public static boolean isMatching(ICVSRepositoryLocation location1,
			ICVSRepositoryLocation location2) {
		if (isCompatible(location1, location2, true)
				&& location2.getMethod() == location1.getMethod()
				&& location2.getPort() == location1.getPort())
			return true;
		return false;
	}

	static boolean isPromptRequired(Map suggestedRepositoryLocations) {
		if (suggestedRepositoryLocations == null)
			return false;
		for (Iterator i = suggestedRepositoryLocations.values().iterator(); i
				.hasNext();) {
			List list = (List) i.next();
			if (!list.isEmpty())
				return true;
		}
		return false;
	}

}