/*******************************************************************************
 * Copyright (c) 2014, 2017 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
 *******************************************************************************/
package org.eclipse.handly.model.impl;

import static org.eclipse.handly.context.Contexts.of;
import static org.eclipse.handly.context.Contexts.with;
import static org.eclipse.handly.util.ToStringOptions.FORMAT_STYLE;

import java.lang.reflect.Array;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.handly.context.IContext;
import org.eclipse.handly.model.Elements;
import org.eclipse.handly.model.IElement;
import org.eclipse.handly.model.IModel;
import org.eclipse.handly.util.ToStringOptions.FormatStyle;

/**
 * All {@link IElement}s must implement this interface.
 *
 * @noextend This interface is not intended to be extended by clients.
 */
public interface IElementImpl
    extends IElement
{
    /**
     * Returns the name of this element, or <code>null</code>
     * if this element has no name. This is a handle-only method.
     *
     * @return the element name, or <code>null</code> if this element has no name
     */
    String getName_();

    /**
     * Returns the element directly containing this element,
     * or <code>null</code> if this element has no parent.
     * This is a handle-only method.
     *
     * @return the parent element, or <code>null</code> if this element has
     *  no parent
     */
    IElement getParent_();

    /**
     * Returns the root element containing this element.
     * Returns this element if it has no parent.
     * This is a handle-only method.
     *
     * @return the root element (never <code>null</code>)
     */
    default IElement getRoot_()
    {
        IElement parent = getParent_();
        if (parent == null)
            return this;
        else
            return Elements.getRoot(parent);
    }

    /**
     * Returns the closest ancestor of this element that has the given type.
     * Returns <code>null</code> if no such ancestor can be found.
     * This is a handle-only method.
     *
     * @param ancestorType the given type (not <code>null</code>)
     * @return the closest ancestor of this element that has the given type,
     *  or <code>null</code> if no such ancestor can be found
     */
    default <T> T getAncestor_(Class<T> ancestorType)
    {
        IElement parent = getParent_();
        if (parent == null)
            return null;
        if (ancestorType.isInstance(parent))
            return ancestorType.cast(parent);
        return Elements.getAncestor(parent, ancestorType);
    }

    /**
     * Returns the model that owns this element. This is a handle-only method.
     *
     * @return the element's model (never <code>null</code>)
     */
    IModel getModel_();

    /**
     * Returns the innermost resource enclosing this element, or <code>null</code>
     * if this 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>
     *
     * @return the innermost resource enclosing this element, or <code>null</code>
     *  if this element is not enclosed in a workspace resource
     */
    IResource getResource_();

    /**
     * Returns a file system location for this element. The resulting URI is
     * suitable to passing to <code>EFS.getStore(URI)</code>. Returns
     * <code>null</code> if no location can be determined.
     *
     * @return a file system location for this element,
     *  or <code>null</code> if no location can be determined
     */
    default URI getLocationURI_()
    {
        IResource resource = getResource_();
        if (resource != null)
            return resource.getLocationURI();
        return null;
    }

    /**
     * Returns whether this 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>
     *
     * @return <code>true</code> if this element exists in the model, and
     *  <code>false</code> if this element does not exist
     */
    boolean exists_();

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

    /**
     * Returns the immediate children of this element that have the given type.
     * Unless otherwise specified by the implementing element, the children
     * are in no particular order.
     *
     * @param childType the given type (not <code>null</code>)
     * @return the immediate children of this element that have the given type
     *  (never <code>null</code>). Clients <b>must not</b> modify the returned
     *  array.
     * @throws CoreException if this element does not exist or if an
     *  exception occurs while accessing its corresponding resource
     */
    default <T> T[] getChildren_(Class<T> childType) throws CoreException
    {
        IElement[] children = getChildren_();
        if (childType.isAssignableFrom(children.getClass().getComponentType()))
        {
            @SuppressWarnings("unchecked")
            T[] result = (T[])children;
            return result;
        }
        List<T> list = new ArrayList<T>(children.length);
        for (IElement child : children)
        {
            if (childType.isInstance(child))
                list.add(childType.cast(child));
        }
        @SuppressWarnings("unchecked")
        T[] result = (T[])Array.newInstance(childType, list.size());
        return list.toArray(result);
    }

    /**
     * Returns a string representation of this 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 advised 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 context not <code>null</code>
     * @return a string representation of this element (never <code>null</code>)
     */
    String toString_(IContext context);

    /**
     * Returns a string representation of this 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 context not <code>null</code>
     * @return a string representation of this element (never <code>null</code>)
     */
    default String toDisplayString_(IContext context)
    {
        FormatStyle style = context.getOrDefault(FORMAT_STYLE);
        if (style != FormatStyle.SHORT && style != FormatStyle.MEDIUM)
            context = with(of(FORMAT_STYLE, FormatStyle.MEDIUM), context);
        return toString_(context);
    }
}
