/*******************************************************************************
 * Copyright (c) 2010, 2020 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
 *     George Suaridze <suag@1c.ru> (1C-Soft LLC) - Bug 560168
 *******************************************************************************/

package org.eclipse.help.internal.base.scope;

import java.util.ArrayList;
import java.util.Collections;
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;

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 boolean initialized = false;

	private static class RegistryHolder {
		static final ScopeRegistry instance = new ScopeRegistry();
	}

	private ScopeRegistry() {
	}

	public static ScopeRegistry getInstance() {
		return RegistryHolder.instance;
	}

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


		// Lookup in scope registry
		for (IScopeHandle handle : scopes) {
			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 (IConfigurationElement element : elements) {

			Object obj = null;
			try {
				obj = element.createExecutableExtension("class"); //$NON-NLS-1$
			} catch (CoreException e) {
				Platform.getLog(getClass()).error("Create extension failed:[" + SCOPE_XP_NAME + "].", e); //$NON-NLS-1$ //$NON-NLS-2$
			}
			if (obj instanceof AbstractHelpScope) {
				String id = element.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 (String phrase : phrases) {
			AbstractHelpScope scope = parseScopePhrase(phrase);
			if (scope!=null)
				scopes.add(scope);
		}

		if (scopes.isEmpty())
			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
	 *
	 */
	static 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.isEmpty())
				return null;
			return next;
		}

		private String format(String next,char current)
		{
			if (next.isEmpty())
			{
				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 static 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;
			}
		}
	}
}
