/*******************************************************************************
 * Copyright (c) 2014, 2016 1C-Soft LLC 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:
 *     Vladimir Piskarev (1C) - initial API and implementation
 *     (inspired by Eclipse JDT work)
 *******************************************************************************/
package org.eclipse.handly.model;

import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT;

import java.net.URI;
import java.util.Objects;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.handly.buffer.IBuffer;
import org.eclipse.handly.context.IContext;
import org.eclipse.handly.internal.Activator;
import org.eclipse.handly.model.impl.IElementImpl;
import org.eclipse.handly.model.impl.ISourceElementImpl;
import org.eclipse.handly.model.impl.ISourceFileImpl;
import org.eclipse.handly.snapshot.ISnapshot;
import org.eclipse.handly.snapshot.StaleSnapshotException;
import org.eclipse.handly.util.Property;
import org.eclipse.handly.util.TextRange;

/**
 * Provides methods for generic access to elements of a Handly-based model.
 * <p>
 * Methods annotated as "handle-only" do not require underlying elements
 * to exist. Methods that require underlying elements to exist throw a
 * <code>CoreException</code> when the underlying element is missing.
 * </p>
 * <p>
 * Note that despite having a dependency on {@link IResource} and {@link IFile}
 * this class can safely be used even when <code>org.eclipse.core.resources</code>
 * bundle is not available. This is based on the "outward impression" of late
 * resolution of symbolic references a JVM must provide according to the JVMS.
 * </p>
 *
 * @see IElement
 */
public class Elements
{
    /**
     * Returns the name of the element, or <code>null</code>
     * if the element has no name. This is a handle-only method.
     *
     * @param element not <code>null</code>
     * @return the element name, or <code>null</code> if the element has no name
     */
    public static String getName(IElement element)
    {
        return ((IElementImpl)element).hName();
    }

    /**
     * Returns the immediate parent of the element,
     * or <code>null</code> if the element has no parent.
     * This is a handle-only method.
     *
     * @param element not <code>null</code>
     * @return the parent element, or <code>null</code> if the element has
     *  no parent
     */
    public static IElement getParent(IElement element)
    {
        return ((IElementImpl)element).hParent();
    }

    /**
     * Returns the root element for the element.
     * Returns the element itself if it has no parent.
     * This is a handle-only method.
     *
     * @param element not <code>null</code>
     * @return the root element (never <code>null</code>)
     */
    public static IElement getRoot(IElement element)
    {
        return ((IElementImpl)element).hRoot();
    }

    /**
     * Returns the element's closest ancestor that has the given type.
     * Returns <code>null</code> if no such ancestor can be found.
     * This is a handle-only method.
     *
     * @param element not <code>null</code>
     * @param ancestorType the given type (not <code>null</code>)
     * @return the closest ancestor element that has the given type,
     *  or <code>null</code> if no such ancestor can be found
     */
    public static <T> T getAncestor(IElement element, Class<T> ancestorType)
    {
        return ((IElementImpl)element).hAncestor(ancestorType);
    }

    /**
     * Returns the model that owns the element. This is a handle-only method.
     * <p>
     * Note that the relationship between an element and its owing model does
     * not change over the lifetime of an element.
     * </p>
     *
     * @param element not <code>null</code>
     * @return the element's model (never <code>null</code>)
     */
    public static IModel getModel(IElement element)
    {
        return ((IElementImpl)element).hModel();
    }

    /**
     * Returns the innermost resource enclosing the element, or <code>null</code>
     * if the element is not enclosed in a workspace resource.
     * This is a handle-only method.
     * <p>
     * Note that it is safe to call this method and test the return value
     * for <code>null</code> even when <code>org.eclipse.core.resources</code>
     * bundle is not available.
     * </p>
     *
     * @param element not <code>null</code>
     * @return the innermost resource enclosing the element, or <code>null</code>
     *  if the element is not enclosed in a workspace resource
     */
    public static IResource getResource(IElement element)
    {
        return ((IElementImpl)element).hResource();
    }

    /**
     * Returns a file system location for the element. The resulting URI is
     * suitable to passing to <code>EFS.getStore(URI)</code>. Returns
     * <code>null</code> if no location can be determined.
     *
     * @param element not <code>null</code>
     * @return a file system location for the element,
     *  or <code>null</code> if no location can be determined
     */
    public static URI getLocationURI(IElement element)
    {
        return ((IElementImpl)element).hLocationURI();
    }

    /**
     * Returns whether the element exists in the model.
     * <p>
     * Handles may or may not be backed by an actual element. Handles that are
     * backed by an actual element are said to "exist". It is always the case
     * that if an element exists, then its parent also exists (provided
     * it has one) and includes that element as one of its children.
     * It is therefore possible to navigate to any existing element
     * from the root element along a chain of existing elements.
     * </p>
     *
     * @param element not <code>null</code>
     * @return <code>true</code> if the element exists in the model, and
     *  <code>false</code> if the element does not exist
     */
    public static boolean exists(IElement element)
    {
        return ((IElementImpl)element).hExists();
    }

    /**
     * Returns the immediate children of the element. Unless otherwise specified
     * by the implementing element, the children are in no particular order.
     *
     * @param element not <code>null</code>
     * @return the immediate children of the element (never <code>null</code>).
     *  Clients <b>must not</b> modify the returned array.
     * @throws CoreException if the element does not exist or if an
     *  exception occurs while accessing its corresponding resource
     */
    public static IElement[] getChildren(IElement element) throws CoreException
    {
        return ((IElementImpl)element).hChildren();
    }

    /**
     * Returns the immediate children of the element that have the given type.
     * Unless otherwise specified by the implementing element, the children are
     * in no particular order.
     *
     * @param element not <code>null</code>
     * @param childType the given type (not <code>null</code>)
     * @return the immediate children of the element that have the given type
     *  (never <code>null</code>). Clients <b>must not</b> modify the returned
     *  array.
     * @throws CoreException if the element does not exist or if an
     *  exception occurs while accessing its corresponding resource
     */
    public static <T> T[] getChildren(IElement element, Class<T> childType)
        throws CoreException
    {
        return ((IElementImpl)element).hChildren(childType);
    }

    /**
     * Returns a string representation of the element in a form suitable for
     * debugging purposes. Clients can influence the result with format options
     * specified in the given context; unrecognized options are ignored and
     * an empty context is permitted.
     * <p>
     * Implementations are encouraged to support common options defined in
     * {@link org.eclipse.handly.util.ToStringOptions ToStringOptions} and
     * interpret the format style as follows:
     * </p>
     * <ul>
     * <li>{@link org.eclipse.handly.util.ToStringOptions.FormatStyle#FULL FULL}
     * - A full representation that lists ancestors and children.</li>
     * <li>{@link org.eclipse.handly.util.ToStringOptions.FormatStyle#LONG LONG}
     * - A long representation that lists children but not ancestors.</li>
     * <li>{@link org.eclipse.handly.util.ToStringOptions.FormatStyle#MEDIUM MEDIUM}
     * - A compact representation that lists ancestors but not children.</li>
     * <li>{@link org.eclipse.handly.util.ToStringOptions.FormatStyle#SHORT SHORT}
     * - A minimal representation that does not list ancestors or children.</li>
     * </ul>
     *
     * @param element not <code>null</code>
     * @param context not <code>null</code>
     * @return a string representation of the element (never <code>null</code>)
     */
    public static String toString(IElement element, IContext context)
    {
        return ((IElementImpl)element).hToString(context);
    }

    /**
     * Returns a string representation of the element in a form suitable for
     * displaying to the user, e.g. in message dialogs. Clients can influence
     * the result with format options specified in the given context;
     * unrecognized options are ignored and an empty context is permitted.
     * <p>
     * Implementations are encouraged to support common options defined in
     * {@link org.eclipse.handly.util.ToStringOptions ToStringOptions} and may
     * interpret the format style as they see fit in a way that is specific to
     * the model. No hard rules apply, but usually the string representation
     * does not list the element's children regardless of the format style, and
     * a {@link org.eclipse.handly.util.ToStringOptions.FormatStyle#FULL FULL}
     * representation fully identifies the element within the model.
     * </p>
     *
     * @param element not <code>null</code>
     * @param context not <code>null</code>
     * @return a string representation of the element (never <code>null</code>)
     */
    public static String toDisplayString(IElement element, IContext context)
    {
        return ((IElementImpl)element).hToDisplayString(context);
    }

    /**
     * Returns whether the given elements are equal and have the same parent.
     *
     * @param e1 the first element (not <code>null</code>)
     * @param e2 the second element (may be <code>null</code>)
     * @return <code>true</code> if the given elements are equal and have
     *  the same parent, <code>false</code> otherwise
     */
    public static boolean equalsAndSameParent(IElement e1, IElement e2)
    {
        if (!e1.equals(e2))
            return false;

        return Objects.equals(getParent(e1), getParent(e2));
    }

    /**
     * Returns the smallest element that includes the given source position,
     * or <code>null</code> if the given position is not within the source range
     * of the given element. If no finer grained element is found at the
     * position, the given element itself is returned.
     *
     * @param context a source element (not <code>null</code>)
     * @param position a source position (0-based)
     * @param base a snapshot on which the given position is based,
     *  or <code>null</code> if the snapshot is unknown or doesn't matter
     * @return the innermost element enclosing the given source position,
     *  or <code>null</code> if none (including the given element itself)
     * @throws CoreException if the given element does not exist or if an
     *  exception occurs while accessing its corresponding resource
     * @throws StaleSnapshotException if snapshot inconsistency is detected,
     *  i.e. the given element's current structure and properties are based on
     *  a different snapshot
     */
    public static ISourceElement getSourceElementAt(ISourceElement context,
        int position, ISnapshot base) throws CoreException
    {
        return ((ISourceElementImpl)context).hSourceElementAt(position, base);
    }

    /**
     * Returns the smallest element that includes the given position,
     * or <code>null</code> if the given position is not within the source
     * range of the given element, or if the given element does not exist or
     * an exception occurs while accessing its corresponding resource, or if
     * snapshot inconsistency is detected. If no finer grained element is
     * found at the position, the given element itself is returned.
     *
     * @param context a source element (not <code>null</code>)
     * @param position a source position (0-based)
     * @param base a snapshot on which the given position is based,
     *  or <code>null</code> if the snapshot is unknown or doesn't matter
     * @return the innermost element enclosing the given source position,
     *  or <code>null</code> if none (including the given element itself)
     */
    public static ISourceElement getSourceElementAt2(ISourceElement context,
        int position, ISnapshot base)
    {
        try
        {
            return getSourceElementAt(context, position, base);
        }
        catch (CoreException e)
        {
            if (!exists(context))
                ; // this is considered normal
            else
                Activator.log(e.getStatus());
        }
        catch (StaleSnapshotException e)
        {
            // ignore
        }
        return null;
    }

    /**
     * Returns an object holding cached structure and properties for the
     * source element.
     *
     * @param element not <code>null</code>
     * @return {@link ISourceElementInfo} for the element
     *  (never <code>null</code>)
     * @throws CoreException if the element does not exist or if an
     *  exception occurs while accessing its corresponding resource
     */
    public static ISourceElementInfo getSourceElementInfo(
        ISourceElement element) throws CoreException
    {
        return ((ISourceElementImpl)element).hSourceElementInfo();
    }

    /**
     * Returns an object holding cached structure and properties for the
     * source element, or {@link #NO_SOURCE_ELEMENT_INFO} if no such info
     * is available.
     *
     * @param element not <code>null</code>
     * @return {@link ISourceElementInfo} for the element
     *  (never <code>null</code>)
     */
    public static ISourceElementInfo getSourceElementInfo2(
        ISourceElement element)
    {
        try
        {
            return getSourceElementInfo(element);
        }
        catch (CoreException e)
        {
            if (!exists(element))
                ; // this is considered normal
            else
                Activator.log(e.getStatus());
        }
        return NO_SOURCE_ELEMENT_INFO;
    }

    /**
     * A 'null object' indicating that no info is available for source element,
     * e.g. because the element does not exist.
     * <p>
     * The instance methods return either <code>null</code> (if allowed
     * by the method contract) or an appropriate 'null object' (such as
     * a zero-length array).
     * </p>
     * @see ISourceElementInfo
     * @see #getSourceElementInfo2(ISourceElement)
     */
    public static final ISourceElementInfo NO_SOURCE_ELEMENT_INFO =
        new NoSourceElementInfo();

    private static class NoSourceElementInfo
        implements ISourceElementInfo
    {
        static final ISourceConstruct[] NO_CHILDREN = new ISourceConstruct[0];

        @Override
        public ISnapshot getSnapshot()
        {
            return null;
        }

        @Override
        public <T> T get(Property<T> property)
        {
            return null;
        }

        @Override
        public ISourceConstruct[] getChildren()
        {
            return NO_CHILDREN;
        }

        @Override
        public TextRange getFullRange()
        {
            return null;
        }

        @Override
        public TextRange getIdentifyingRange()
        {
            return null;
        }
    };

    /**
     * Returns the source file that contains the given element,
     * or <code>null</code> if the given element is not contained in a
     * source file. Returns the given element itself if it is a source file.
     *
     * @param element not <code>null</code>
     * @return the source file containing the given element,
     *  or <code>null</code> if none
     */
    public static ISourceFile getSourceFile(ISourceElement element)
    {
        if (element instanceof ISourceFile)
            return (ISourceFile)element;
        else
            return getAncestor(element, ISourceFile.class);
    }

    /**
     * Ensures that, if the given element is contained in a source file,
     * the source file is reconciled. Note that the call may result in
     * change of existence status for the given element: if the element
     * did not exist before, it may be brought into existence; conversely,
     * if the element existed, it may cease to exist.
     *
     * @param element not <code>null</code>
     * @param monitor a progress monitor, or <code>null</code>
     *  if progress reporting is not desired
     * @return <code>true</code> if the call completed successfully,
     *  <code>false</code> in case of a failure
     * @throws OperationCanceledException if this method is canceled
     */
    public static boolean ensureReconciled(ISourceElement element,
        IProgressMonitor monitor)
    {
        ISourceFile sourceFile = getSourceFile(element);
        if (sourceFile != null)
        {
            try
            {
                reconcile(sourceFile, monitor);
            }
            catch (CoreException e)
            {
                Activator.log(e.getStatus());
                return false;
            }
        }
        return true;
    }

    /**
     * Returns the underlying {@link IFile}, or <code>null</code>
     * if the source file has no underlying file in the workspace.
     * This is a handle-only method.
     * <p>
     * This method returns the same value as {@link #getResource(IElement)},
     * but saves a downcast.
     * </p>
     *
     * @param sourceFile not <code>null</code>
     * @return the underlying <code>IFile</code>, or <code>null</code>
     *  if the source file has no underlying file in the workspace
     */
    public static IFile getFile(ISourceFile sourceFile)
    {
        return ((ISourceFileImpl)sourceFile).hFile();
    }

    /**
     * Returns whether the source file is a working copy.
     *
     * @param sourceFile not <code>null</code>
     * @return <code>true</code> if the source file is a working copy,
     *  <code>false</code> otherwise
     */
    public static boolean isWorkingCopy(ISourceFile sourceFile)
    {
        return ((ISourceFileImpl)sourceFile).hIsWorkingCopy();
    }

    /**
     * Returns whether the source file needs reconciling.
     * A source file needs reconciling if it is a working copy and
     * its buffer has been modified since the last time it was reconciled.
     *
     * @param sourceFile not <code>null</code>
     * @return <code>true</code> if the source file needs reconciling,
     *  <code>false</code> otherwise
     */
    public static boolean needsReconciling(ISourceFile sourceFile)
    {
        return ((ISourceFileImpl)sourceFile).hNeedsReconciling();
    }

    /**
     * Makes the working copy consistent with its buffer by updating
     * the element's structure and properties as necessary. Does nothing
     * if the source file is not in working copy mode or if the working copy
     * is already consistent with its buffer.
     *
     * @param sourceFile not <code>null</code>
     * @param monitor a progress monitor, or <code>null</code>
     *  if progress reporting is not desired
     * @throws CoreException if the working copy cannot be reconciled
     * @throws OperationCanceledException if this method is canceled
     */
    public static void reconcile(ISourceFile sourceFile,
        IProgressMonitor monitor) throws CoreException
    {
        reconcile(sourceFile, EMPTY_CONTEXT, monitor);
    }

    /**
     * Makes the working copy consistent with its buffer by updating
     * the element's structure and properties as necessary. Does nothing
     * if the source file is not in working copy mode.
     * <p>
     * Implementations are encouraged to support the following standard options,
     * which may be specified in the given context:
     * </p>
     * <ul>
     * <li>
     * {@link #FORCE_RECONCILING} - Indicates whether reconciling has to be
     *  performed even if the working copy is already consistent with its buffer.
     * </li>
     * </ul>
     *
     * @param sourceFile not <code>null</code>
     * @param context the operation context (not <code>null</code>)
     * @param monitor a progress monitor, or <code>null</code>
     *  if progress reporting is not desired
     * @throws CoreException if the working copy cannot be reconciled
     * @throws OperationCanceledException if this method is canceled
     */
    public static void reconcile(ISourceFile sourceFile, IContext context,
        IProgressMonitor monitor) throws CoreException
    {
        ((ISourceFileImpl)sourceFile).hReconcile(context, monitor);
    }

    /**
     * Indicates whether reconciling has to be performed even if
     * the working copy is already consistent with its buffer.
     * Default value: <code>false</code>.
     * @see #reconcile(ISourceFile, IContext, IProgressMonitor)
     */
    public static final Property<Boolean> FORCE_RECONCILING = Property.get(
        Elements.class.getName() + ".forceReconciling", //$NON-NLS-1$
        Boolean.class).withDefault(false);

    /**
     * Returns the buffer opened for the source file. Note that buffers may
     * be shared by multiple clients, so the returned buffer may have unsaved
     * changes if it has been modified by another client.
     * <p>
     * For working copies, the relationship between a source file and its buffer
     * does not change over the lifetime of a working copy. Otherwise, a new
     * buffer may be returned each time this method is invoked.
     * </p>
     * <p>
     * The client takes (potentially shared) ownership of the returned buffer
     * and is responsible for releasing it when finished. The buffer will be
     * disposed only after it is released by every owner. The buffer must not
     * be accessed by clients which don't own it.
     * </p>
     *
     * @param sourceFile not <code>null</code>
     * @return the buffer opened for the source file (never <code>null</code>)
     * @throws CoreException if the source file does not exist
     *  or if its contents cannot be accessed
     * @see IBuffer
     */
    public static IBuffer getBuffer(ISourceFile sourceFile) throws CoreException
    {
        return getBuffer(sourceFile, EMPTY_CONTEXT, null);
    }

    /**
     * Returns the buffer opened for the source file. Note that buffers may
     * be shared by multiple clients, so the returned buffer may have unsaved
     * changes if it has been modified by another client.
     * <p>
     * For working copies, the relationship between a source file and its buffer
     * does not change over the lifetime of a working copy. Otherwise, a new
     * buffer may be returned each time this method is invoked.
     * </p>
     * <p>
     * The client takes (potentially shared) ownership of the returned buffer
     * and is responsible for releasing it when finished. The buffer will be
     * disposed only after it is released by every owner. The buffer must not
     * be accessed by clients which don't own it.
     * </p>
     * <p>
     * Implementations are encouraged to support the following standard options,
     * which may be specified in the given context:
     * </p>
     * <ul>
     * <li>
     * {@link #CREATE_BUFFER} - Indicates whether a new buffer should be created
     * if none already exists for the source file.
     * </li>
     * </ul>
     *
     * @param sourceFile not <code>null</code>
     * @param context the operation context (not <code>null</code>)
     * @param monitor a progress monitor, or <code>null</code>
     *  if progress reporting is not desired
     * @return the buffer opened for the source file. May return <code>null</code>
     *  if <code>CREATE_BUFFER == false</code> and there is no buffer currently
     *  opened for the source file
     * @throws CoreException if the source file does not exist
     *  or if its contents cannot be accessed
     * @throws OperationCanceledException if this method is canceled
     * @see IBuffer
     */
    public static IBuffer getBuffer(ISourceFile sourceFile, IContext context,
        IProgressMonitor monitor) throws CoreException
    {
        return ((ISourceFileImpl)sourceFile).hBuffer(context, monitor);
    }

    /**
     * Indicates whether a new buffer should be created if none already exists
     * for the source file. Default value: <code>true</code>.
     * @see #getBuffer(ISourceFile, IContext, IProgressMonitor)
     */
    public static final Property<Boolean> CREATE_BUFFER = Property.get(
        Elements.class.getName() + ".createBuffer", Boolean.class).withDefault( //$NON-NLS-1$
            true);

    private Elements()
    {
    }
}
