/*******************************************************************************
 * Copyright (c) 2004, 2013 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.debug.internal.ui.memory;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionConverter;
import org.eclipse.core.expressions.ExpressionTagNames;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.memory.AbstractMemoryRenderingBindingsProvider;
import org.eclipse.debug.ui.memory.IMemoryRenderingBindingsListener;
import org.eclipse.debug.ui.memory.IMemoryRenderingBindingsProvider;
import org.eclipse.debug.ui.memory.IMemoryRenderingManager;
import org.eclipse.debug.ui.memory.IMemoryRenderingType;

/**
 * Represents a renderingBindings element of a memoryRenderings contribution.
 *
 * @since 3.1
 */
class RenderingBindings extends AbstractMemoryRenderingBindingsProvider implements IMemoryRenderingBindingsProvider {

	// element
	protected IConfigurationElement fConfigurationElement;

	// cached rendering ids
	private IMemoryRenderingType[] fAllTypes;
	private IMemoryRenderingType[] fRenderingTypes;
	private IMemoryRenderingType[] fDefaultTypes;

	// rendering type provider, or null (optional)
	private IMemoryRenderingBindingsProvider fProvider;

	// optional exprssion
	private Expression fExpression;

	// element attribute
	public static final String ATTR_RENDERING_IDS = "renderingIds"; //$NON-NLS-1$
	public static final String ATTR_DEFAULT_IDS = "defaultIds"; //$NON-NLS-1$
	public static final String ATTR_PRIMARY = "primaryId"; //$NON-NLS-1$
	public static final String ATTR_PROVIDER = "class"; //$NON-NLS-1$

	// empty bindings
	private static final IMemoryRenderingType[] EMPTY = new IMemoryRenderingType[0];

	/**
	 * Constructs a bindings element from the given contribution.
	 *
	 * @param element contribution
	 */
	RenderingBindings(IConfigurationElement element) {
		fConfigurationElement = element;
	}

	/**
	 * Returns the non-default bindings specified by this contribution.
	 *
	 * @return the non-default bindings specified by this contribution
	 */
	private IMemoryRenderingType[] getBindings() {
		if (fRenderingTypes == null) {
			String ids = fConfigurationElement.getAttribute(ATTR_RENDERING_IDS);
			List<IMemoryRenderingType> list = new ArrayList<>();
			IMemoryRenderingManager manager = getManager();
			if (ids != null) {
				String[] strings = ids.split(","); //$NON-NLS-1$
				for (int i = 0; i < strings.length; i++) {
					String id = strings[i].trim();
					IMemoryRenderingType type = manager.getRenderingType(id);
					if (type != null) {
						list.add(type);
					}
				}
			}
			// remove any default bindings, in case of duplicate specification
			IMemoryRenderingType[] defaultBindings = getDefaultBindings();
			for (int i = 0; i < defaultBindings.length; i++) {
				list.remove(defaultBindings[i]);
			}
			fRenderingTypes = list.toArray(new IMemoryRenderingType[list.size()]);
		}
		return fRenderingTypes;
	}

	/**
	 * Returns the default bindings specified by this contribution.
	 *
	 * @return the default bindings specified by this contribution
	 */
	private IMemoryRenderingType[] getDefaultBindings() {
		if (fDefaultTypes == null) {
			String ids = fConfigurationElement.getAttribute(ATTR_DEFAULT_IDS);
			List<IMemoryRenderingType> list = new ArrayList<>();
			IMemoryRenderingManager manager = getManager();
			if (ids != null) {
				String[] strings = ids.split(","); //$NON-NLS-1$
				for (int i = 0; i < strings.length; i++) {
					String id = strings[i].trim();
					IMemoryRenderingType type = manager.getRenderingType(id);
					if (type != null) {
						list.add(type);
					}
				}
			}
			// the primary is also considered a default rendering
			String primaryId = getPrimaryId();
			if (primaryId != null) {
				IMemoryRenderingType type = manager.getRenderingType(primaryId);
				if (type != null) {
					list.add(type);
				}
			}
			fDefaultTypes = list.toArray(new IMemoryRenderingType[list.size()]);
		}
		return fDefaultTypes;
	}

	/**
	 * Returns the primary id, or <code>null</code> if none.
	 *
	 * @return the primary id, or <code>null</code> if none
	 */
	private String getPrimaryId() {
		return fConfigurationElement.getAttribute(ATTR_PRIMARY);
	}

	/**
	 * Returns the provider for this binding or <code>null</code> of none.
	 *
	 * @return the provider for this binding or <code>null</code> of none
	 */
	protected IMemoryRenderingBindingsProvider getProvider(IMemoryBlock memoryBlock) {
		if (isBound(memoryBlock)) {
			if (fProvider == null) {
				String name = fConfigurationElement.getAttribute(ATTR_PROVIDER);
				if (name != null) {
					try {
						fProvider = (IMemoryRenderingBindingsProvider) fConfigurationElement.createExecutableExtension(ATTR_PROVIDER);
					} catch (CoreException e) {
						DebugUIPlugin.log(e);
					}
				}

				if (fProvider != null) {
					fProvider.addListener(new IMemoryRenderingBindingsListener() {
						@Override
						public void memoryRenderingBindingsChanged() {
							fireBindingsChanged();
						}
					});
				}
			}
		}
		return fProvider;
	}

	/**
	 * Returns whether this binding is applies to the given memory block.
	 *
	 * @param block memory block
	 * @return whether this binding is applies to the given memory block
	 */
	private boolean isBound(IMemoryBlock block) {
		Expression expression = getExpression();
		if (expression != null) {
			IEvaluationContext context = DebugUIPlugin.createEvaluationContext(block);
			try {
				return expression.evaluate(context) == EvaluationResult.TRUE;
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
				return false;
			}
		}
		return true;
	}

	/**
	 * Validates this contribution.
	 *
	 * @exception CoreException if invalid
	 */
	void validate() throws CoreException {
		if (fConfigurationElement.getAttribute(ATTR_PROVIDER) != null) {
			if (fConfigurationElement.getAttribute(ATTR_RENDERING_IDS) != null || fConfigurationElement.getAttribute(ATTR_DEFAULT_IDS) != null || fConfigurationElement.getAttribute(ATTR_PRIMARY) != null) {
				Status status = new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "<renderingBindings> element cannot specify other attributes when " + ATTR_PROVIDER + " is present", null); //$NON-NLS-1$ //$NON-NLS-2$
				throw new CoreException(status);
			}
		}
	}

	/**
	 * Returns this binding's enablement expression, or <code>null</code> if
	 * none.
	 *
	 * @return enablement expression, or <code>null</code> if none
	 */
	private Expression getExpression() {
		if (fExpression == null) {
			IConfigurationElement[] elements = fConfigurationElement.getChildren(ExpressionTagNames.ENABLEMENT);
			IConfigurationElement enablement = elements.length > 0 ? elements[0] : null;
			if (enablement != null) {
				try {
					fExpression = ExpressionConverter.getDefault().perform(enablement);
				} catch (CoreException e) {
					DebugUIPlugin.log(e);
				}
			}
		}
		return fExpression;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRenderingBindingsProvider#
	 * getRenderingTypes(org.eclipse.debug.core.model.IMemoryBlock)
	 */
	@Override
	public IMemoryRenderingType[] getRenderingTypes(IMemoryBlock block) {
		if (isBound(block)) {
			IMemoryRenderingBindingsProvider provider = getProvider(block);
			if (provider == null) {
				if (fAllTypes == null) {
					IMemoryRenderingType[] defaultBindings = getDefaultBindings();
					IMemoryRenderingType[] bindings = getBindings();
					fAllTypes = new IMemoryRenderingType[defaultBindings.length + bindings.length];
					for (int i = 0; i < defaultBindings.length; i++) {
						fAllTypes[i] = defaultBindings[i];
					}
					for (int i = 0, j = defaultBindings.length; i < bindings.length; i++, j++) {
						fAllTypes[j] = bindings[i];
					}
				}
				return fAllTypes;
			}
			return provider.getRenderingTypes(block);
		}
		return EMPTY;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRenderingBindingsProvider#
	 * getDefaultRenderingTypes(org.eclipse.debug.core.model.IMemoryBlock)
	 */
	@Override
	public IMemoryRenderingType[] getDefaultRenderingTypes(IMemoryBlock block) {
		if (isBound(block)) {
			IMemoryRenderingBindingsProvider provider = getProvider(block);
			if (provider == null) {
				return getDefaultBindings();
			}
			return provider.getDefaultRenderingTypes(block);
		}
		return EMPTY;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.ui.memory.IMemoryRenderingBindingsProvider#
	 * getPrimaryRenderingType(org.eclipse.debug.core.model.IMemoryBlock)
	 */
	@Override
	public IMemoryRenderingType getPrimaryRenderingType(IMemoryBlock block) {
		if (isBound(block)) {
			IMemoryRenderingBindingsProvider provider = getProvider(block);
			if (provider == null) {
				String primaryId = getPrimaryId();
				if (primaryId != null) {
					return getManager().getRenderingType(primaryId);
				}
			} else {
				return provider.getPrimaryRenderingType(block);
			}
		}
		return null;
	}

	private IMemoryRenderingManager getManager() {
		return DebugUITools.getMemoryRenderingManager();
	}

}
