/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Patrick Chuong (Texas Instruments) - Improve usability of the breakpoint view (Bug 238956)
 *****************************************************************/
package org.eclipse.debug.internal.ui.views.breakpoints;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointContainer;
import org.eclipse.debug.internal.ui.breakpoints.provisional.IBreakpointOrganizer;
import org.eclipse.debug.internal.ui.breakpoints.provisional.OtherBreakpointCategory;
import org.eclipse.debug.internal.ui.model.elements.ElementContentProvider;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
import org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate;
import org.eclipse.debug.internal.ui.viewers.model.provisional.ModelDelta;
import org.eclipse.debug.ui.IDebugUIConstants;

/**
 * This class contains the list of container or a list of breakpoint, elements are sorted according to rules
 * in the comparator.
 */
public class BreakpointContainer extends ElementContentProvider implements IAdaptable, IBreakpointContainer {
	/**
	 * Child breakpoints - inserting new element into this collection should use the insertBreakpoint method
	 */
	final private List<IBreakpoint> fBreakpoints = new ArrayList<IBreakpoint>();

    /**
     * Child containers - inserting new element into this container should use the insertChildContainer method
     */
	final private List<BreakpointContainer> fChildContainers = new ArrayList<BreakpointContainer>();

    /**
     * The category for this container
     */
    private IAdaptable fCategory;

    /**
     * The breakpoint organizer for this container
     */
    private IBreakpointOrganizer fOrganizer;

    /**
     * The nested breakpoint organizer
     */
    private IBreakpointOrganizer[] fNesting;

    /**
     * A flag to indicate this is the default container
     */
    private boolean fDefaultContainer;

    /**
     * Parent container
     */
    private BreakpointContainer fParent;

    /**
     * The comparator, will be use to compare the order for inserting new element into this container
     */
    private ElementComparator fComparator;

    /**
     * Constructor, intended to be call when creating the root container.
     *
     * @param organizers the breakpoint organizer for this container
     * @param comparator the element comparator, can be <code>null</code>. If <code>null</code> than new element
     * will be added to the end of the list.
     */
    public BreakpointContainer(IBreakpointOrganizer[] organizers, ElementComparator comparator) {
    	fNesting = organizers;
    	fComparator = comparator;
    }

    /**
     * Constructor, intended to be call within this class only.
     *
     * @param parent the parent breakpoint container
     * @param category the category for this container
     * @param organizer the organizer for this container
     * @param comparator the element comparator
     * @param nesting the nested breakpoint organizer
     */
    private BreakpointContainer(BreakpointContainer parent, IAdaptable category, IBreakpointOrganizer organizer,
    		ElementComparator comparator, IBreakpointOrganizer[] nesting) {
    	this(category, organizer, nesting);
    	fParent = parent;
    	fComparator = comparator;
    }

    /**
     * Constructor, intended to be call when reorganizing the content.
     *
     * @param category the breakpoint category
     * @param organizer the breakpoint organizer
     * @param nesting the nested breakpoint organizer
     */
    BreakpointContainer(IAdaptable category, IBreakpointOrganizer organizer, IBreakpointOrganizer[] nesting) {
    	fCategory = category;
    	fOrganizer = organizer;
    	fNesting = nesting;
    }

    /**
     * Initialize the default containers.
     *
     * @param parentDelta the parent delta, addition child delta will be added to the parent
     */
    public void initDefaultContainers(ModelDelta parentDelta) {
    	// seed with all nested categories
    	if (fNesting != null && fNesting.length > 0) {
    		IAdaptable[] emptyCategories = fNesting[0].getCategories();
    		if (emptyCategories != null) {
    			for (int i = 0; i < emptyCategories.length; i++) {
    				IAdaptable empty = emptyCategories[i];
    				BreakpointContainer container = findExistingContainer(fChildContainers, empty);
    				if (container == null) {
    					IBreakpointOrganizer[] siblings = new IBreakpointOrganizer[fNesting.length - 1];
    					System.arraycopy(fNesting, 1, siblings, 0, siblings.length);
    					container = new BreakpointContainer(this, empty, fNesting[0], fComparator, siblings);
    					insertChildContainer(container);
    					container.fDefaultContainer = true;

    					int size = container.getChildren().length;
    					parentDelta.addNode(container, fChildContainers.indexOf(container), IModelDelta.INSTALL|IModelDelta.ADDED|IModelDelta.EXPAND, size);

    				}
    			}
    		}
    	}
    }

    /**
     * Insert the breakpoint to this container.
     *
     * @param breakpoint the new breakpoint
     * @return the index of the breakpoint in the cache, -1 if the breakpoint already exist
     */
    private int insertBreakpoint(IBreakpoint breakpoint) {
    	if (fBreakpoints.contains(breakpoint) || breakpoint == null) {
    		return -1;
    	}
    	int index = fBreakpoints.size();
    	for (; fComparator != null && index > 0; index--) {
    		if (fComparator.compare(fBreakpoints.get(index-1), breakpoint) < 0) {
				break;
			}
    	}
    	if (index < 0) {
    		index = 0;
    	}
    	fBreakpoints.add(index, breakpoint);
    	return index;
    }

    /**
     * Insert the child container this container.
     *
     * @param container the child container
     * @return the index of the container in the cache, -1 if the child container already exist
     */
    private int insertChildContainer(BreakpointContainer container) {
    	int index = fChildContainers.size();
    	for (; fComparator != null && index > 0; index--) {
    		if (fComparator.compare(fChildContainers.get(index-1), container) < 0) {
				break;
			}
    	}

    	if (index < 0) {
			index = 0;
		}
    	fChildContainers.add(index, container);

    	return index;
    }


    /**
     * Returns the element comparator.
     *
     * @return the element comparator
     */
    public ElementComparator getElementComparator() {
    	return fComparator;
    }

    /**
     * Returns the parent container, can be <code>null</code>.
     *
     * @return the parent container
     */
    public BreakpointContainer getParent() {
    	return fParent;
    }

    /**
     * Determine whether there is any nested container.
     *
     * @return true if has nested container
     */
    private boolean hasNesting() {
    	return fNesting != null && fNesting.length > 0;
    }

    /**
     * Get the categories for the breakpoint with the given organizer.
     *
     * @param breakpoint the breakpoint
     * @param organizer the organizer
     * @return the categories
     */
    private static IAdaptable[] getCategories(IBreakpoint breakpoint, IBreakpointOrganizer organizer) {
    	IAdaptable[] categories = organizer.getCategories(breakpoint);
    	if (categories == null || categories.length == 0) {
			categories = OtherBreakpointCategory.getCategories(organizer);
		}
    	return categories;
    }

    /**
     * Find existing breakpoint container in the container array the given category.
     *
     * @param containers the container array
     * @param category the category
     * @return the breakpoint container, can be <code>null</code>.
     */
	private static BreakpointContainer findExistingContainer(List<BreakpointContainer> containers, IAdaptable category) {
		for (BreakpointContainer c : containers) {
    		if (category.equals(c.getCategory())) {
				return c;
			}
    	}
    	return null;
    }

    // TODO [pchuong]: can be remove if BreakpointsContentProvider no longer uses this class
    void addBreakpoint(IBreakpoint breakpoint) {
    	addBreakpoint(breakpoint, new ModelDelta(null, IModelDelta.NO_CHANGE));
    }

    /**
     * Add a breakpoint to the container, additional delta will be added to the root delta.
     *
     * @param breakpoint the breakpoint to added
     * @param rootDelta the root delta of this container
     * @see #removeBreakpoint
     */
    public void addBreakpoint(IBreakpoint breakpoint, ModelDelta rootDelta) {
    	final int bpIndex = insertBreakpoint(breakpoint);
    	if (bpIndex < 0) {
			return;
		}

        if (hasNesting()) {
            IBreakpointOrganizer organizer = fNesting[0];

            // get the breakpoint categories from the organizer
            IAdaptable[] categories = getCategories(breakpoint, organizer);

            for (int i = 0; i < categories.length; ++i) {
            	ModelDelta childDelta = null;
            	IAdaptable category = categories[i];
            	BreakpointContainer container = findExistingContainer(fChildContainers, category);

            	// create a new container if it doesn't exist
            	if (container == null) {
            		IBreakpointOrganizer[] nesting = null;
            		if (fNesting.length > 1) {
            			 nesting = new IBreakpointOrganizer[fNesting.length - 1];
                         System.arraycopy(fNesting, 1, nesting, 0, nesting.length);
            		}
            		container = new BreakpointContainer(this, category, organizer, fComparator, nesting);
            		insertChildContainer(container);
            		childDelta = rootDelta.addNode(container, fChildContainers.indexOf(container), IModelDelta.INSERTED|IModelDelta.INSTALL, -1);

            	} else {
					childDelta = rootDelta.addNode(container, fChildContainers.indexOf(container), IModelDelta.STATE, -1);
            	}

           		container.addBreakpoint(breakpoint, childDelta);
           		childDelta.setChildCount(container.getChildren().length);
            }

        } else {
        	// TODO [pchuong]: There seems to be some kind of problem when the INSERTED flag is used,
        	//				   there is a additional checkbox added to the end of the tree.
        	//				   Also the tree seems to have a strange visual effect when using the INSERTED
        	//				   flag for the child node instead of ADDED flag. Note: all breakpoint delta
        	//				   is using the ADDED flag in this class.
       		rootDelta.addNode(breakpoint, bpIndex, IModelDelta.ADDED|IModelDelta.INSTALL, 0);
       		// rootDelta.addNode(breakpoint, bpIndex, IModelDelta.INSERTED|IModelDelta.INSTALL, 0);

        	rootDelta.setFlags(rootDelta.getFlags() | IModelDelta.EXPAND);
        }
    }

    /**
     * Remove a breakpoint from the container, additional delta will be added to the root delta.
     *
     * @param breakpoint the breakpoint to remove
     * @param rootDelta the root delta of this container
     * @return if the breakpoint was successfully removed
     * @see #addBreakpoint
     */
    public boolean removeBreakpoint(IBreakpoint breakpoint, ModelDelta rootDelta) {
    	boolean removed = fBreakpoints.remove(breakpoint);

    	if (removed) {
    		boolean addRemoveBpDelta = getContainers().length == 0;

			Iterator<BreakpointContainer> it = fChildContainers.iterator();
    		while (it.hasNext()) {
    			BreakpointContainer container = it.next();
				// if the breakpoint contains in the container and it is the only breakpoint,
				// than remove the container from the collection
    			if (container.contains(breakpoint)) {
    				ModelDelta childDelta = null;
    				if ((!container.isDefaultContainer()) && (container.getBreakpoints().length <= 1)) {
	    				it.remove();
	    				childDelta = rootDelta.addNode(container, IModelDelta.REMOVED|IModelDelta.UNINSTALL);

	    			} else {
	    				childDelta = rootDelta.addNode(container, IModelDelta.STATE);
	    			}
    				// remove the breakpoint from the nested containers
	    			container.removeBreakpoint(breakpoint, childDelta);
    			}
    		}

    		if (addRemoveBpDelta) {
    			rootDelta.addNode(breakpoint, IModelDelta.REMOVED|IModelDelta.UNINSTALL);
    		}
    	}
    	return removed;
    }

    /**
     * A helper method to copy the organizers between two containers.
     *
     * @param destContainer the destination container
     * @param sourceContainer the source container
     */
    public static void copyOrganizers(BreakpointContainer destContainer, BreakpointContainer sourceContainer) {
    	destContainer.fNesting = sourceContainer.fNesting;
    	destContainer.fOrganizer = sourceContainer.fOrganizer;
		destContainer.fCategory = sourceContainer.fCategory;
    }

    /**
     * A helper method to update the breakpoint cache of the container and it's ancestors.
     *
     * @param container the breakpoint container
     * @param breakpoints the breakpoint to update
     * @param add true if breakpoint should be added to the cache, otherwise remove the breakpoint from the cache
     */
	private static void updateSelfAndAncestorsBreakpointCache(BreakpointContainer container, List<IBreakpoint> breakpoints, boolean add) {
    	if (container != null) {
    		container.fBreakpoints.removeAll(breakpoints);
    		if (add) {
				container.fBreakpoints.addAll(breakpoints);
			}
    		updateSelfAndAncestorsBreakpointCache(container.getParent(), breakpoints, add);
    	}
    }

    /**
     * A helper method to add a breakpoint to an existing container.
     *
     * @param destContainer the destination container
     * @param breakpoint the breakpoint to add
     * @param destContainerDelta the destination container delta, additional delta will be added to this delta
     */
    static public void addBreakpoint(BreakpointContainer destContainer, IBreakpoint breakpoint, ModelDelta destContainerDelta) {
    	int index = destContainer.insertBreakpoint(breakpoint);
    	Assert.isTrue(index >= 0);

		List<IBreakpoint> breakpoints = destContainer.fBreakpoints;
    	destContainerDelta.addNode(breakpoint, index/*breakpoints.indexOf(breakpoint)*/, IModelDelta.ADDED|IModelDelta.INSTALL, 0);
    	destContainerDelta.setFlags(destContainerDelta.getFlags() | IModelDelta.EXPAND);

    	// add the breakpoints to the parent containers.
    	updateSelfAndAncestorsBreakpointCache(destContainer.getParent(), breakpoints, true);
    }

    /**
     * A helper method to add a child container to an existing container.
     *
     * @param destContainer the destination container
     * @param sourceContainer the source container
     * @param destContainerDelta the delta of the destination container, additional delta will be added to this delta
     */
    static public void addChildContainer(BreakpointContainer destContainer, BreakpointContainer sourceContainer, ModelDelta destContainerDelta) {
    	destContainer.insertChildContainer(sourceContainer);
    	sourceContainer.fParent = destContainer;

    	// add the breakpoints to the parent containers.
		List<IBreakpoint> breakpoints = Arrays.asList(sourceContainer.getBreakpoints());
    	updateSelfAndAncestorsBreakpointCache(destContainer, breakpoints, true);

    	int index = destContainer.fChildContainers.indexOf(sourceContainer);
    	int size = sourceContainer.getChildren().length;
    	ModelDelta childDelta  = destContainerDelta.addNode(sourceContainer, index, IModelDelta.INSERTED|IModelDelta.INSTALL|IModelDelta.EXPAND, size);

    	appendContainerDelta(sourceContainer, childDelta);
    }

    /**
     * A helper method to append delta to the breakpoint container. This method is used by addContainer only.
     *
     * @param container the container to append child delta
     * @param containerDelta the delta of the breakpoint container, additional delta will be added to this delta
     */
    static private void appendContainerDelta(BreakpointContainer container, ModelDelta containerDelta) {
    	Object[] children = container.getChildren();
    	for (int i = 0; i < children.length; ++i) {
    		boolean isBreakpoint = children[0] instanceof IBreakpoint;
    		int numChild =  isBreakpoint ? 0 : children.length;
    		int flag = isBreakpoint ? IModelDelta.ADDED|IModelDelta.INSTALL
    				: IModelDelta.INSERTED|IModelDelta.INSTALL|IModelDelta.EXPAND;
    		ModelDelta childDelta = containerDelta.addNode(children[i], i, flag, numChild);

    		if (children[i] instanceof BreakpointContainer) {
    			BreakpointContainer childContainer = (BreakpointContainer) children[i];
    			appendContainerDelta(childContainer, childDelta);
    		}
    	}
    }

    /**
     * A helper method to remove the breakpoint from the container.
     *
     * @param container the container to remove the breakpoint
     * @param breakpoint the breakpoint to remove
     * @param containerDelta the delta of the breakpoint container, additional delta will be added to this delta
     */
    static public void removeBreakpoint(BreakpointContainer container, IBreakpoint breakpoint, ModelDelta containerDelta) {
    	container.removeBreakpoint(breakpoint, containerDelta);
		List<IBreakpoint> breakpoints = new ArrayList<IBreakpoint>();
    	breakpoints.add(breakpoint);
    	updateSelfAndAncestorsBreakpointCache(container.getParent(), breakpoints, false);
    }

    /**
     * Remove all child elements including the given container itself.
     *
     * @param container the breakpoint container
     * @param delta the parent delta
     */
    static public void removeAll(BreakpointContainer container, ModelDelta delta) {
    	BreakpointContainer parent = container.getParent();
    	if (parent != null) {
    		parent.fChildContainers.remove(container);
    		delta = delta.addNode(container, IModelDelta.UNINSTALL|IModelDelta.REMOVED);
    	}

    	if (container.fChildContainers.size() == 0) {
			List<IBreakpoint> breakpoints = new ArrayList<IBreakpoint>();
			Iterator<IBreakpoint> iterator = container.fBreakpoints.iterator();
    		while (iterator.hasNext()) {
				IBreakpoint obj = iterator.next();
				breakpoints.add(obj);
				delta.addNode(obj, IModelDelta.UNINSTALL|IModelDelta.REMOVED);
				iterator.remove();
    		}

	    	// remove the breakpoints from the parent containers.
			updateSelfAndAncestorsBreakpointCache(container.getParent(), breakpoints, false);
    		return;
    	}

		Iterator<BreakpointContainer> iterator = container.fChildContainers.iterator();
    	while (iterator.hasNext()) {
    		BreakpointContainer childContainer = iterator.next();
    		ModelDelta childDelta = delta.addNode(childContainer, IModelDelta.REMOVED|IModelDelta.UNINSTALL);
    		iterator.remove();
    		removeAll(childContainer, childDelta);
    	}
    }

    /**
     * Returns whether this is the default container.
     *
     * @return true if it is a default container
     */
    boolean isDefaultContainer() {
    	return fDefaultContainer;
    }

    /**
     * Returns the breakpoints in this container
     *
     * @return the breakpoints in this container
     */
    @Override
	public IBreakpoint[] getBreakpoints() {
        return fBreakpoints.toArray(new IBreakpoint[fBreakpoints.size()]);
    }

    /**
     * Returns this container's category.
     *
     * @return container category
     */
    @Override
	public IAdaptable getCategory() {
        return fCategory;
    }

    /**
     * Returns children as breakpoints or nested containers.
     *
     * @return children as breakpoints or nested containers
     */
    public Object[] getChildren() {
        if (fChildContainers.isEmpty()) {
            return getBreakpoints();
        }
        return getContainers();
    }

    /**
     * Returns the index of the given child element (breakpoint or container.
     *
     * @param child Child to calculate index of.
     * @return index of child
     */
    public int getChildIndex(Object child) {
        if (fChildContainers.isEmpty()) {
            return fBreakpoints.indexOf(child);
        }
        return fChildContainers.indexOf(child);
    }

    /**
     * Returns the containers nested in this container, possibly empty.
     *
     * @return the containers nested in this container, can be empty.
     */
    public BreakpointContainer[] getContainers() {
        return fChildContainers.toArray(new BreakpointContainer[fChildContainers.size()]);
    }

    /**
     * Returns this container's organizer.
     *
     * @return this container's organizer
     */
    @Override
	public IBreakpointOrganizer getOrganizer() {
        return fOrganizer;
    }

    /**
     * Returns whether this container contains the given breakpoint.
     *
     * @param breakpoint the breakpoint to check
     * @return true if this container contains the given breakpoint
     */
    @Override
	public boolean contains(IBreakpoint breakpoint) {
        return fBreakpoints.contains(breakpoint);
    }

    /**
     * Returns the child containers for the given breakpoint.
     *
     * @param breakpoint the breakpoint to get containers for
     * @return child containers
     */
    public BreakpointContainer[] getContainers(IBreakpoint breakpoint) {
        if (contains(breakpoint)) {
        	BreakpointContainer[] containers = getContainers();
            if (containers.length == 0) {
                return new BreakpointContainer[]{this};
            }
			ArrayList<BreakpointContainer> list = new ArrayList<BreakpointContainer>();
            for (int i = 0; i < containers.length; i++) {
            	BreakpointContainer container = containers[i];
            	BreakpointContainer[] subcontainers = container.getContainers(breakpoint);
                if (subcontainers != null) {
                    for (int j = 0; j < subcontainers.length; j++) {
                        list.add(subcontainers[j]);
                    }
                }
            }
            return list.toArray(new BreakpointContainer[list.size()]);
        }
        return new BreakpointContainer[0];
    }

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
        if (obj instanceof BreakpointContainer) {
        	BreakpointContainer container = (BreakpointContainer) obj;
            // With Group by "Advanced" the same category can contain a different subset of breakpoints,
            // therefore to have the same category is not enough to be equal.
            if (! (fParent != null && container.fParent != null && fParent.equals(container.fParent) ||
            		fParent == null && container.fParent == null) ) {
                return false;
            }
        	if (getCategory() != null && container.getCategory() != null) {
        		return getCategory().equals(container.getCategory());
        	} else {
        		return true;
        	}
        }
        return super.equals(obj);
	}

    /*
     * (non-Javadoc)
     * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildCount(java.lang.Object, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
     */
	@Override
	protected int getChildCount(Object element, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
		return getChildren().length;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#getChildren(java.lang.Object, int, int, org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext, org.eclipse.debug.internal.ui.viewers.model.provisional.IViewerUpdate)
	 */
	@Override
	protected Object[] getChildren(Object parent, int index, int length, IPresentationContext context, IViewerUpdate monitor) throws CoreException {
		return getElements(getChildren(), index, length);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.debug.internal.ui.model.elements.ElementContentProvider#supportsContextId(java.lang.String)
	 */
	@Override
	protected boolean supportsContextId(String id) {
		return id.equals(IDebugUIConstants.ID_BREAKPOINT_VIEW);
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}
}
