/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 * 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
 *
 *******************************************************************************/
package org.eclipse.dltk.core.search.matching2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A set of matches and possible matches, which need to be resolved.
 */
public abstract class MatchingNodeSet<E>
		implements IMatchingNodeSet<E>, Comparator<E> {
	/**
	 * Map of matching ast nodes that don't need to be resolved to their
	 * accuracy level. Each node is removed as it is reported.
	 */
	private Map<E, MatchLevel> matchingNodes = new HashMap<>();

	// sourceRange -> node
	private HashtableOfLong<E> matchingNodesKeys = new HashtableOfLong<>();

	/**
	 * Set of possible matching ast nodes. They need to be resolved to determine
	 * if they really match the search pattern.
	 */
	private Set<E> possibleMatchingNodes = new HashSet<>();

	// sourceRange -> node
	private HashtableOfLong<E> possibleMatchingNodesKeys = new HashtableOfLong<>();

	@Override
	public MatchLevel addMatch(E node, MatchLevel matchLevel) {
		switch (matchLevel) {
		case POSSIBLE_MATCH:
			addPossibleMatch(node);
			break;
		case INACCURATE_MATCH:
			addTrustedMatch(node, MatchLevel.INACCURATE_MATCH);
			break;
		case ACCURATE_MATCH:
			addTrustedMatch(node, MatchLevel.ACCURATE_MATCH);
			break;
		}
		return matchLevel;
	}

	public void addPossibleMatch(E node) {
		// remove existing node at same position from set
		// (case of recovery that created the same node several time
		// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
		long key = computeNodeKey(node);
		E existing = this.possibleMatchingNodesKeys.get(key);
		if (existing != null && existing.getClass().equals(node.getClass()))
			this.possibleMatchingNodes.remove(existing);
		// add node to set
		this.possibleMatchingNodes.add(node);
		this.possibleMatchingNodesKeys.put(key, node);
	}

	private void addTrustedMatch(E node, MatchLevel level) {
		// remove existing node at same position from set
		// (case of recovery that created the same node several time
		// see http://bugs.eclipse.org/bugs/show_bug.cgi?id=29366)
		long key = computeNodeKey(node);
		E existing = this.matchingNodesKeys.get(key);
		if (existing != null && existing.getClass().equals(node.getClass()))
			this.matchingNodes.remove(existing);
		// map node to its accuracy level
		this.matchingNodes.put(node, level);
		this.matchingNodesKeys.put(key, node);
	}

	protected boolean hasPossibleNodes(int start, int end) {
		for (E node : possibleMatchingNodes) {
			if (checkRange(node, start, end)) {
				return true;
			}
		}
		for (E node : matchingNodes.keySet()) {
			if (checkRange(node, start, end)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns the matching nodes that are in the given range in the source
	 * order.
	 */
	public List<E> matchingNodes(int start, int end) {
		List<E> nodes = null;
		for (E node : matchingNodes.keySet()) {
			if (checkRange(node, start, end)) {
				if (nodes == null)
					nodes = new ArrayList<>();
				nodes.add(node);
			}
		}
		if (nodes == null)
			return Collections.emptyList();
		Collections.sort(nodes, this);
		return nodes;
	}

	/**
	 * Returns all the matching nodes
	 */
	public List<E> matchingNodes() {
		final List<E> nodes = new ArrayList<>(matchingNodes.keySet());
		Collections.sort(nodes, this);
		return nodes;
	}

	public boolean removePossibleMatch(E node) {
		long key = computeNodeKey(node);
		E existing = this.possibleMatchingNodesKeys.get(key);
		if (existing == null)
			return false;
		this.possibleMatchingNodesKeys.put(key, null);
		return this.possibleMatchingNodes.remove(node);
	}

	protected abstract long computeNodeKey(E node);

	protected abstract boolean checkRange(E node, int start, int end);

	public MatchLevel removeTrustedMatch(E node) {
		long key = computeNodeKey(node);
		E existing = this.matchingNodesKeys.get(key);
		if (existing == null)
			return null;
		this.matchingNodesKeys.put(key, null);
		return this.matchingNodes.remove(node);
	}

	@Override
	public String toString() {
		StringBuilder result = new StringBuilder();
		result.append("Exact matches:"); //$NON-NLS-1$
		List<E> nodes = new ArrayList<>(matchingNodes.keySet());
		Collections.sort(nodes, this);
		for (E node : nodes) {
			result.append("\n\t"); //$NON-NLS-1$
			result.append(matchingNodes.get(node));
			result.append(' ');
			result.append(describeNode(node));
		}
		result.append("\nPossible matches:"); //$NON-NLS-1$
		nodes.clear();
		nodes.addAll(possibleMatchingNodes);
		Collections.sort(nodes, this);
		for (E node : nodes) {
			result.append("\nPOSSIBLE_MATCH: "); //$NON-NLS-1$
			result.append(describeNode(node));
		}
		return result.toString();
	}

	protected String describeNode(E node) {
		return node.toString();
	}

	public void clear() {
		matchingNodes.clear();
		matchingNodesKeys.clear();
		clearPossibleMatchingNodes();
		// possibleMatchingNodes.clear();
		// possibleMatchingNodesKeys.clear();
	}

	public void clearPossibleMatchingNodes() {
		possibleMatchingNodes.clear();
		possibleMatchingNodesKeys.clear();
	}

	public Collection<E> getPossibleMatchingNodes() {
		return possibleMatchingNodes;
	}

	public int countMatchingNodes() {
		return matchingNodes.size();
	}

	public int countPossibleMatchingNodes() {
		return possibleMatchingNodes.size();
	}

	/**
	 * @return
	 */
	public boolean isEmpty() {
		return matchingNodes.isEmpty() && possibleMatchingNodes.isEmpty();
	}

}
