/*******************************************************************************
 * Copyright (c) 2011, 2017 NumberFour AG and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     NumberFour AG - initial API and Implementation (Alex Panchenko)
 *******************************************************************************/
package org.eclipse.dltk.compiler.problem;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.dltk.compiler.util.Util;
import org.eclipse.dltk.internal.core.InternalDLTKLanguageManager;

public class ProblemCategoryManager {
	private static final String ID_ATTR = "id";
	private static final String NATURE_ATTR = "nature";
	private static final String SCOPE_ATTR = "scope";

	private static final String CATEGORY_ELEMENT = "problemCategory";
	private static final String PROBLEM_ELEMENT = "problem";

	private static ProblemCategoryManager instance = null;

	public static synchronized ProblemCategoryManager getInstance() {
		if (instance == null) {
			instance = new ProblemCategoryManager();
		}
		return instance;
	}

	static class Key {
		final String natureId;
		final String scopeId;

		public Key(String natureId, String scopeId) {
			this.natureId = natureId;
			this.scopeId = scopeId != null ? scopeId : Util.EMPTY_STRING;
		}

		@Override
		public int hashCode() {
			return natureId.hashCode() * 13 + scopeId.hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof Key) {
				final Key other = (Key) obj;
				return natureId.equals(other.natureId)
						&& scopeId.equals(other.scopeId);
			}
			return false;
		}
	}

	private final Map<Key, ScopeDescriptor> scopes = new HashMap<>();

	@SuppressWarnings("serial")
	static class ScopeDescriptor extends HashMap<String, ProblemCategory> {

	}

	@SuppressWarnings("serial")
	static class ProblemCategory extends HashSet<IProblemIdentifier>
			implements IProblemCategory {

		private final String name;
		private final Collection<IProblemIdentifier> contents;

		public ProblemCategory(String name) {
			this.name = name;
			contents = Collections.unmodifiableCollection(this);
		}

		@Override
		public String name() {
			return name;
		}

		@Override
		public Collection<IProblemIdentifier> contents() {
			return contents;
		}

	}

	/**
	 * returns an array (empty is nothing can be found) of all the category ids
	 * that can be found for this problem.
	 *
	 * @param natureId
	 * @param scopeId
	 * @param problem
	 * @return
	 */
	public String[] getID(String natureId, String scopeId,
			IProblemIdentifier problem) {
		Assert.isNotNull(natureId);
		ScopeDescriptor scope = getScope(natureId, scopeId);
		if (scope == null)
			return new String[0];
		Iterator<Entry<String, ProblemCategory>> iterator = scope.entrySet()
				.iterator();
		List<String> ids = new ArrayList<>();
		while (iterator.hasNext()) {
			Entry<String, ProblemCategory> entry = iterator.next();
			if (entry.getValue().contains(problem)) {
				ids.add(entry.getKey());
			}
		}
		return ids.toArray(new String[ids.size()]);
	}

	public IProblemCategory getCategory(String natureId, String scopeId,
			String id) {
		Assert.isNotNull(natureId);
		ScopeDescriptor scope = getScope(natureId, scopeId);
		if (scope == null)
			return null;
		return scope.get(id);
	}

	/**
	 * @param natureId
	 * @param scopeId
	 * @return
	 */
	private ScopeDescriptor getScope(String natureId, String scopeId) {
		final Key scopeKey = new Key(natureId, scopeId);
		ScopeDescriptor scope;
		synchronized (scopes) {
			scope = scopes.get(scopeKey);
			if (scope == null && scopes.containsKey(scopeKey)) {
				return null;
			}
		}
		if (scope == null) {
			scope = new ScopeDescriptor();
			final IConfigurationElement[] elements = Platform
					.getExtensionRegistry().getConfigurationElementsFor(
							InternalDLTKLanguageManager.PROBLEM_FACTORY_EXTPOINT);
			for (IConfigurationElement element : elements) {
				if (CATEGORY_ELEMENT.equals(element.getName())
						&& scopeKey.natureId
								.equals(element.getAttribute(NATURE_ATTR))
						&& scopeKey.scopeId
								.equals(element.getAttribute(SCOPE_ATTR))) {
					final String categoryId = element.getAttribute(ID_ATTR);
					if (categoryId != null) {
						ProblemCategory category = scope.get(categoryId);
						if (category == null) {
							category = new ProblemCategory(categoryId);
							scope.put(categoryId, category);
						}
						for (IConfigurationElement problem : element
								.getChildren(PROBLEM_ELEMENT)) {
							final IProblemIdentifier identifier = DefaultProblemIdentifier
									.decode(problem.getValue());
							if (identifier != null
									&& !(identifier instanceof ProblemIdentifierInt)
									&& !(identifier instanceof ProblemIdentifierString)) {
								category.add(identifier);
							}
						}
					}
				}
			}
			synchronized (scopes) {
				scopes.put(scopeKey, scope);
			}
		}
		return scope;
	}
}
