/*******************************************************************************
 * Copyright (c) 2010, 2015 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.help.internal.base.scope;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.help.base.AbstractHelpScope;
import org.eclipse.help.base.IHelpScopeProducer;
import org.eclipse.help.base.IScopeHandle;
import org.eclipse.help.internal.base.HelpBasePlugin;

public class ScopeRegistry {

	public static final String SCOPE_XP_NAME = "org.eclipse.help.base.scope"; //$NON-NLS-1$
	public static final String ENABLEMENT_SCOPE_ID = "org.eclipse.help.enablement"; //$NON-NLS-1$
	public static final String SEARCH_SCOPE_SCOPE_ID = "org.eclipse.help.searchscope"; //$NON-NLS-1$

	public static final String SCOPE_AND = "^"; //$NON-NLS-1$
	public static final String SCOPE_OR = "|"; //$NON-NLS-1$

	private static List<IScopeHandle> scopes = null;

	private static ScopeRegistry instance;

	private boolean initialized = false;

	private ScopeRegistry() {
	}

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

	public AbstractHelpScope getScope(String id) {
		if (id == null) {
			return new UniversalScope();
		}
		readScopes();


		// Lookup in scope registry
		for (Iterator<IScopeHandle> iter = scopes.iterator(); iter.hasNext();) {
			IScopeHandle handle = iter.next();
			if (id.equals(handle.getId())) {
				return handle.getScope();
			}
		}
		return null;
	}

	synchronized private void readScopes() {
		if (initialized ) {
			return;
		}
		scopes = new ArrayList<>();
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IConfigurationElement[] elements = registry
				.getConfigurationElementsFor(SCOPE_XP_NAME);
		for (int i = 0; i < elements.length; i++) {

			Object obj = null;
			try {
				obj = elements[i].createExecutableExtension("class"); //$NON-NLS-1$
			} catch (CoreException e) {
				HelpBasePlugin.logError("Create extension failed:[" //$NON-NLS-1$
						+ SCOPE_XP_NAME + "].", e); //$NON-NLS-1$
			}
			if (obj instanceof AbstractHelpScope) {
				String id = elements[i].getAttribute("id"); //$NON-NLS-1$
				IScopeHandle filter = new ScopeHandle(id, (AbstractHelpScope) obj);
				scopes.add(filter);
			}
			else if (obj instanceof IHelpScopeProducer)
			{
				IScopeHandle dynamicScopes[] = ((IHelpScopeProducer)obj).getScopeHandles();
				Collections.addAll(scopes, dynamicScopes);
			}
		}
		initialized = true;
	}

	public IScopeHandle[] getScopes() {
		readScopes();
		return scopes.toArray(new IScopeHandle[scopes.size()]);
	}

	/**
	 * Parse logical sets of Scopes.  All phrases in the
	 * array are intersected together
	 *
	 * @param phrases
	 * @return
	 */
	public AbstractHelpScope parseScopePhrases(String phrases[])
	{
		ArrayList<AbstractHelpScope> scopes = new ArrayList<>();

		for (int p=0;p<phrases.length;p++)
		{
			AbstractHelpScope scope = parseScopePhrase(phrases[p]);
			if (scope!=null)
				scopes.add(scope);
		}

		if (scopes.size()==0)
			return null;
		if (scopes.size()==1)
			return scopes.get(0);
		return new IntersectionScope(
				scopes.toArray(
						new AbstractHelpScope[scopes.size()]));
	}

	/**
	 * Parse a logical phrase of scope names.  i.e.:
	 * (A^B)|C
	 *
	 * @param phrase
	 * @return
	 */
	public AbstractHelpScope parseScopePhrase(String phrase)
	{
		if (!(phrase.startsWith("(") && !phrase.startsWith("("))) //$NON-NLS-1$ //$NON-NLS-2$
			phrase = '('+phrase+')';

		Stack<TempScope> scopeStack = new Stack<>();
		ScopePhrase scopePhrase = new ScopePhrase(phrase);

		String elem;

		while ((elem = scopePhrase.getNextElement())!=null)
		{
			if (elem.equals("(")) //$NON-NLS-1$
			{
				TempScope scope = new TempScope();
				scope.setType(TempScope.SELF);
				scopeStack.push(scope);
			}
			else if (elem.equals(")")) //$NON-NLS-1$
			{
				TempScope scope = scopeStack.pop();
				if (scopeStack.isEmpty())
					return scope.getScope();
				else{
					TempScope parent = scopeStack.peek();
					parent.add(scope.getScope());
				}
			}
			else if (elem.equals(SCOPE_AND))
			{
				TempScope scope = scopeStack.peek();
				scope.setType(TempScope.INTERSECTION);
			}
			else if (elem.equals(SCOPE_OR))
			{
				TempScope scope = scopeStack.peek();
				scope.setType(TempScope.UNION);
			}
			else
			{
				TempScope scope = scopeStack.peek();
				AbstractHelpScope helpScope = getScope(elem);
				if (helpScope!=null)
					scope.add(helpScope);
			}
		}
		return null;
	}

	/**
	 * A class used to parse a logical scope phrase, by
	 * returning each part of the phrase as a separate element
	 *
	 */
	class ScopePhrase{

		private String phrase;
		private int cursor;

		public ScopePhrase(String phrase)
		{
			this.phrase = phrase;
			this.cursor = 0;
		}

		public String getNextElement()
		{
			String next = ""; //$NON-NLS-1$

			for (;cursor<phrase.length();cursor++)
			{
				char current = phrase.charAt(cursor);
				if (current=='(')
					return format(next,current);
				if (current==')')
					return format(next,current);
				if ((current+"").equals(SCOPE_AND)) //$NON-NLS-1$
					return format(next,current);
				if ((current+"").equals(SCOPE_OR)) //$NON-NLS-1$
					return format(next,current);
				next+=current;
			}
			if (next.equals("")) //$NON-NLS-1$
				return null;
			return next;
		}

		private String format(String next,char current)
		{
			if (next.equals("")) //$NON-NLS-1$
			{
				cursor++;
				return current+""; //$NON-NLS-1$
			}
			else
				return next;
		}
	}

	/**
	 * A class used to contruct a logical AbstractHelpScope based
	 * on one Scope, or a union/intersection of scopes.
	 *
	 */
	private class TempScope
	{
		public final static int SELF=0;
		public final static int UNION=1;
		public final static int INTERSECTION=2;

		private ArrayList<AbstractHelpScope> kids = new ArrayList<>();
		private int type;

		public void setType(int type)
		{
			this.type = type;
		}

		public void add(AbstractHelpScope kid)
		{
			kids.add(kid);
		}

		public AbstractHelpScope getScope()
		{
			switch (type){
			case UNION:
				return new UnionScope(
						kids.toArray(
								new AbstractHelpScope[kids.size()]));
			case INTERSECTION:
				return new IntersectionScope(
						kids.toArray(
								new AbstractHelpScope[kids.size()]));
			default:
				if (kids.size()>=1)
					return kids.get(0);
				else
					return null;
			}
		}
	}
}
