/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.resources;

import static com.android.SdkConstants.ANDROID_PREFIX;
import static com.android.SdkConstants.ANDROID_STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.ATTR_COLOR;
import static com.android.SdkConstants.ATTR_NAME;
import static com.android.SdkConstants.ATTR_TYPE;
import static com.android.SdkConstants.DOT_XML;
import static com.android.SdkConstants.EXT_XML;
import static com.android.SdkConstants.FD_RESOURCES;
import static com.android.SdkConstants.FD_RES_VALUES;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.TAG_ITEM;
import static com.android.SdkConstants.TAG_RESOURCES;
import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP;

import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.resources.ResourceDeltaKind;
import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.resources.ResourceUrl;
import com.android.ide.common.resources.configuration.CountryCodeQualifier;
import com.android.ide.common.resources.configuration.DensityQualifier;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.resources.configuration.KeyboardStateQualifier;
import com.android.ide.common.resources.configuration.LayoutDirectionQualifier;
import com.android.ide.common.resources.configuration.LocaleQualifier;
import com.android.ide.common.resources.configuration.NavigationMethodQualifier;
import com.android.ide.common.resources.configuration.NavigationStateQualifier;
import com.android.ide.common.resources.configuration.NetworkCodeQualifier;
import com.android.ide.common.resources.configuration.NightModeQualifier;
import com.android.ide.common.resources.configuration.ResourceQualifier;
import com.android.ide.common.resources.configuration.ScreenDimensionQualifier;
import com.android.ide.common.resources.configuration.ScreenHeightQualifier;
import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
import com.android.ide.common.resources.configuration.ScreenRatioQualifier;
import com.android.ide.common.resources.configuration.ScreenSizeQualifier;
import com.android.ide.common.resources.configuration.ScreenWidthQualifier;
import com.android.ide.common.resources.configuration.SmallestScreenWidthQualifier;
import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
import com.android.ide.common.resources.configuration.TouchScreenQualifier;
import com.android.ide.common.resources.configuration.UiModeQualifier;
import com.android.ide.common.resources.configuration.VersionQualifier;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.Hyperlinks;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils;
import com.android.ide.eclipse.adt.internal.editors.layout.refactoring.VisualRefactoring;
import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard;
import com.android.resources.FolderTypeRelationship;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
import com.android.utils.Pair;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.xml.core.internal.document.ElementImpl;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * Helper class to deal with SWT specifics for the resources.
 */
@SuppressWarnings("restriction") // XML model
public class ResourceHelper {

    private final static Map<Class<?>, Image> sIconMap = new HashMap<Class<?>, Image>(
            FolderConfiguration.getQualifierCount());

    static {
        try {
            IconFactory factory = IconFactory.getInstance();
            sIconMap.put(CountryCodeQualifier.class,        factory.getIcon("mcc")); //$NON-NLS-1$
            sIconMap.put(NetworkCodeQualifier.class,        factory.getIcon("mnc")); //$NON-NLS-1$
            sIconMap.put(LocaleQualifier.class,             factory.getIcon("language")); //$NON-NLS-1$
            sIconMap.put(LayoutDirectionQualifier.class,    factory.getIcon("bidi")); //$NON-NLS-1$
            sIconMap.put(ScreenSizeQualifier.class,         factory.getIcon("size")); //$NON-NLS-1$
            sIconMap.put(ScreenRatioQualifier.class,        factory.getIcon("ratio")); //$NON-NLS-1$
            sIconMap.put(ScreenOrientationQualifier.class,  factory.getIcon("orientation")); //$NON-NLS-1$
            sIconMap.put(UiModeQualifier.class,             factory.getIcon("dockmode")); //$NON-NLS-1$
            sIconMap.put(NightModeQualifier.class,          factory.getIcon("nightmode")); //$NON-NLS-1$
            sIconMap.put(DensityQualifier.class,            factory.getIcon("dpi")); //$NON-NLS-1$
            sIconMap.put(TouchScreenQualifier.class,        factory.getIcon("touch")); //$NON-NLS-1$
            sIconMap.put(KeyboardStateQualifier.class,      factory.getIcon("keyboard")); //$NON-NLS-1$
            sIconMap.put(TextInputMethodQualifier.class,    factory.getIcon("text_input")); //$NON-NLS-1$
            sIconMap.put(NavigationStateQualifier.class,    factory.getIcon("navpad")); //$NON-NLS-1$
            sIconMap.put(NavigationMethodQualifier.class,   factory.getIcon("navpad")); //$NON-NLS-1$
            sIconMap.put(ScreenDimensionQualifier.class,    factory.getIcon("dimension")); //$NON-NLS-1$
            sIconMap.put(VersionQualifier.class,            factory.getIcon("version")); //$NON-NLS-1$
            sIconMap.put(ScreenWidthQualifier.class,        factory.getIcon("width")); //$NON-NLS-1$
            sIconMap.put(ScreenHeightQualifier.class,       factory.getIcon("height")); //$NON-NLS-1$
            sIconMap.put(SmallestScreenWidthQualifier.class,factory.getIcon("swidth")); //$NON-NLS-1$
        } catch (Throwable t) {
            AdtPlugin.log(t , null);
        }
    }

    /**
     * Returns the icon for the qualifier.
     */
    public static Image getIcon(Class<? extends ResourceQualifier> theClass) {
        return sIconMap.get(theClass);
    }

    /**
     * Returns a {@link ResourceDeltaKind} from an {@link IResourceDelta} value.
     * @param kind a {@link IResourceDelta} integer constant.
     * @return a matching {@link ResourceDeltaKind} or null.
     *
     * @see IResourceDelta#ADDED
     * @see IResourceDelta#REMOVED
     * @see IResourceDelta#CHANGED
     */
    public static ResourceDeltaKind getResourceDeltaKind(int kind) {
        switch (kind) {
            case IResourceDelta.ADDED:
                return ResourceDeltaKind.ADDED;
            case IResourceDelta.REMOVED:
                return ResourceDeltaKind.REMOVED;
            case IResourceDelta.CHANGED:
                return ResourceDeltaKind.CHANGED;
        }

        return null;
    }

    /**
     * Is this a resource that can be defined in any file within the "values" folder?
     * <p>
     * Some resource types can be defined <b>both</b> as a separate XML file as well
     * as defined within a value XML file. This method will return true for these types
     * as well. In other words, a ResourceType can return true for both
     * {@link #isValueBasedResourceType} and {@link #isFileBasedResourceType}.
     *
     * @param type the resource type to check
     * @return true if the given resource type can be represented as a value under the
     *         values/ folder
     */
    public static boolean isValueBasedResourceType(ResourceType type) {
        List<ResourceFolderType> folderTypes = FolderTypeRelationship.getRelatedFolders(type);
        for (ResourceFolderType folderType : folderTypes) {
            if (folderType == ResourceFolderType.VALUES) {
                return true;
            }
        }

        return false;
    }

    /**
     * Is this a resource that is defined in a file named by the resource plus the XML
     * extension?
     * <p>
     * Some resource types can be defined <b>both</b> as a separate XML file as well as
     * defined within a value XML file along with other properties. This method will
     * return true for these resource types as well. In other words, a ResourceType can
     * return true for both {@link #isValueBasedResourceType} and
     * {@link #isFileBasedResourceType}.
     *
     * @param type the resource type to check
     * @return true if the given resource type is stored in a file named by the resource
     */
    public static boolean isFileBasedResourceType(ResourceType type) {
        List<ResourceFolderType> folderTypes = FolderTypeRelationship.getRelatedFolders(type);
        for (ResourceFolderType folderType : folderTypes) {
            if (folderType != ResourceFolderType.VALUES) {

                if (type == ResourceType.ID) {
                    // The folder types for ID is not only VALUES but also
                    // LAYOUT and MENU. However, unlike resources, they are only defined
                    // inline there so for the purposes of isFileBasedResourceType
                    // (where the intent is to figure out files that are uniquely identified
                    // by a resource's name) this method should return false anyway.
                    return false;
                }

                return true;
            }
        }

        return false;
    }

    /**
     * Returns true if this class can create the given resource
     *
     * @param resource the resource to be created
     * @return true if the {@link #createResource} method can create this resource
     */
    public static boolean canCreateResource(String resource) {
        // Cannot create framework resources
        if (resource.startsWith(ANDROID_PREFIX)) {
            return false;
        }

        ResourceUrl parsed = ResourceUrl.parse(resource);
        if (parsed != null) {
            if (parsed.framework) {
                return false;
            }
            ResourceType type = parsed.type;
            String name = parsed.name;

            // Make sure the name is valid
            ResourceNameValidator validator =
                ResourceNameValidator.create(false, (Set<String>) null /* existing */, type);
            if (validator.isValid(name) != null) {
                return false;
            }

            return canCreateResourceType(type);
        }

        return false;
    }

    /**
     * Returns true if this class can create resources of the given resource
     * type
     *
     * @param type the type of resource to be created
     * @return true if the {@link #createResource} method can create resources
     *         of this type (provided the name parameter is also valid)
     */
    public static boolean canCreateResourceType(ResourceType type) {
        // We can create all value types
        if (isValueBasedResourceType(type)) {
            return true;
        }

        // We can create -some- file-based types - those supported by the New XML wizard:
        for (ResourceFolderType folderType : FolderTypeRelationship.getRelatedFolders(type)) {
            if (NewXmlFileWizard.canCreateXmlFile(folderType)) {
                return true;
            }
        }

        return false;
    }

    /** Creates a file-based resource, like a layout. Used by {@link #createResource} */
    private static Pair<IFile,IRegion> createFileResource(IProject project, ResourceType type,
            String name) {

        ResourceFolderType folderType = null;
        for (ResourceFolderType f : FolderTypeRelationship.getRelatedFolders(type)) {
            if (NewXmlFileWizard.canCreateXmlFile(f)) {
                folderType = f;
                break;
            }
        }
        if (folderType == null) {
            return null;
        }

        // Find "dimens.xml" file in res/values/ (or corresponding name for other
        // value types)
        IPath projectPath = new Path(FD_RESOURCES + WS_SEP + folderType.getName() + WS_SEP
            + name + '.' + EXT_XML);
        IFile file = project.getFile(projectPath);
        return NewXmlFileWizard.createXmlFile(project, file, folderType);
    }

    /**
     * Creates a resource of a given type, name and (if applicable) value
     *
     * @param project the project to contain the resource
     * @param type the type of resource
     * @param name the name of the resource
     * @param value the value of the resource, if it is a value-type resource
     * @return a pair of the file containing the resource and a region where the value
     *         appears
     */
    public static Pair<IFile,IRegion> createResource(IProject project, ResourceType type,
            String name, String value) {
        if (!isValueBasedResourceType(type)) {
            return createFileResource(project, type, name);
        }

        // Find "dimens.xml" file in res/values/ (or corresponding name for other
        // value types)
        String typeName = type.getName();
        String fileName = typeName + 's';
        String projectPath = FD_RESOURCES + WS_SEP + FD_RES_VALUES + WS_SEP
            + fileName + '.' + EXT_XML;
        Object editRequester = project;
        IResource member = project.findMember(projectPath);
        String tagName = Hyperlinks.getTagName(type);
        boolean createEmptyTag = type == ResourceType.ID;
        if (member != null) {
            if (member instanceof IFile) {
                IFile file = (IFile) member;
                // File exists: Must add item to the XML
                IModelManager manager = StructuredModelManager.getModelManager();
                IStructuredModel model = null;
                try {
                    model = manager.getExistingModelForEdit(file);
                    if (model == null) {
                        model = manager.getModelForEdit(file);
                    }
                    if (model instanceof IDOMModel) {
                        model.beginRecording(editRequester, String.format("Add %1$s",
                                type.getDisplayName()));
                        IDOMModel domModel = (IDOMModel) model;
                        Document document = domModel.getDocument();
                        Element root = document.getDocumentElement();
                        IStructuredDocument structuredDocument = model.getStructuredDocument();
                        Node lastElement = null;
                        NodeList childNodes = root.getChildNodes();
                        String indent = null;
                        for (int i = childNodes.getLength() - 1; i >= 0; i--) {
                            Node node = childNodes.item(i);
                            if (node.getNodeType() == Node.ELEMENT_NODE) {
                                lastElement = node;
                                indent = AndroidXmlEditor.getIndent(structuredDocument, node);
                                break;
                            }
                        }
                        if (indent == null || indent.length() == 0) {
                            indent = "    "; //$NON-NLS-1$
                        }
                        Node nextChild = lastElement != null ? lastElement.getNextSibling() : null;
                        Text indentNode = document.createTextNode('\n' + indent);
                        root.insertBefore(indentNode, nextChild);
                        Element element = document.createElement(tagName);
                        if (createEmptyTag) {
                            if (element instanceof ElementImpl) {
                                ElementImpl elementImpl = (ElementImpl) element;
                                elementImpl.setEmptyTag(true);
                            }
                        }
                        element.setAttribute(ATTR_NAME, name);
                        if (!tagName.equals(typeName)) {
                            element.setAttribute(ATTR_TYPE, typeName);
                        }
                        root.insertBefore(element, nextChild);
                        IRegion region = null;

                        if (createEmptyTag) {
                            IndexedRegion domRegion = VisualRefactoring.getRegion(element);
                            int endOffset = domRegion.getEndOffset();
                            region = new Region(endOffset, 0);
                        } else {
                            Node valueNode = document.createTextNode(value);
                            element.appendChild(valueNode);

                            IndexedRegion domRegion = VisualRefactoring.getRegion(valueNode);
                            int startOffset = domRegion.getStartOffset();
                            int length = domRegion.getLength();
                            region = new Region(startOffset, length);
                        }
                        model.save();
                        return Pair.of(file, region);
                    }
                } catch (Exception e) {
                    AdtPlugin.log(e, "Cannot access XML value model");
                } finally {
                    if (model != null) {
                        model.endRecording(editRequester);
                        model.releaseFromEdit();
                    }
                }
            }

            return null;
        } else {
            // No such file exists: just create it
            String prolog = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; //$NON-NLS-1$
            StringBuilder sb = new StringBuilder(prolog);

            String root = TAG_RESOURCES;
            sb.append('<').append(root).append('>').append('\n');
            sb.append("    "); //$NON-NLS-1$
            sb.append('<');
            sb.append(tagName);
            sb.append(" name=\""); //$NON-NLS-1$
            sb.append(name);
            sb.append('"');
            if (!tagName.equals(typeName)) {
                sb.append(" type=\""); //$NON-NLS-1$
                sb.append(typeName);
                sb.append('"');
            }
            int start, end;
            if (createEmptyTag) {
                sb.append("/>");                             //$NON-NLS-1$
                start = sb.length();
                end = sb.length();
            } else {
                sb.append('>');
                start = sb.length();
                sb.append(value);
                end = sb.length();
                sb.append('<').append('/');
                sb.append(tagName);
                sb.append('>');
            }
            sb.append('\n').append('<').append('/').append(root).append('>').append('\n');
            String result = sb.toString();
            // TODO: Pretty print string (wait until that CL is integrated)
            String error = null;
            try {
                byte[] buf = result.getBytes("UTF8");    //$NON-NLS-1$
                InputStream stream = new ByteArrayInputStream(buf);
                IFile file = project.getFile(new Path(projectPath));
                file.create(stream, true /*force*/, null /*progress*/);
                IRegion region = new Region(start, end - start);
                return Pair.of(file, region);
            } catch (UnsupportedEncodingException e) {
                error = e.getMessage();
            } catch (CoreException e) {
                error = e.getMessage();
            }

            error = String.format("Failed to generate %1$s: %2$s", name, error);
            AdtPlugin.displayError("New Android XML File", error);
        }
        return null;
    }

    /**
     * Returns the theme name to be shown for theme styles, e.g. for "@style/Theme" it
     * returns "Theme"
     *
     * @param style a theme style string
     * @return the user visible theme name
     */
    public static String styleToTheme(String style) {
        if (style.startsWith(STYLE_RESOURCE_PREFIX)) {
            style = style.substring(STYLE_RESOURCE_PREFIX.length());
        } else if (style.startsWith(ANDROID_STYLE_RESOURCE_PREFIX)) {
            style = style.substring(ANDROID_STYLE_RESOURCE_PREFIX.length());
        } else if (style.startsWith(PREFIX_RESOURCE_REF)) {
            // @package:style/foo
            int index = style.indexOf('/');
            if (index != -1) {
                style = style.substring(index + 1);
            }
        }
        return style;
    }

    /**
     * Returns true if the given style represents a project theme
     *
     * @param style a theme style string
     * @return true if the style string represents a project theme, as opposed
     *         to a framework theme
     */
    public static boolean isProjectStyle(String style) {
        assert style.startsWith(STYLE_RESOURCE_PREFIX)
            || style.startsWith(ANDROID_STYLE_RESOURCE_PREFIX) : style;

        return style.startsWith(STYLE_RESOURCE_PREFIX);
    }

    /**
     * Returns the layout resource name for the given layout file, e.g. for
     * /res/layout/foo.xml returns foo.
     *
     * @param layoutFile the layout file whose name we want to look up
     * @return the layout name
     */
    public static String getLayoutName(IFile layoutFile) {
        String layoutName = layoutFile.getName();
        int dotIndex = layoutName.indexOf('.');
        if (dotIndex != -1) {
            layoutName = layoutName.substring(0, dotIndex);
        }
        return layoutName;
    }

    /**
     * Tries to resolve the given resource value to an actual RGB color. For state lists
     * it will pick the simplest/fallback color.
     *
     * @param resources the resource resolver to use to follow color references
     * @param color the color to resolve
     * @return the corresponding {@link RGB} color, or null
     */
    public static RGB resolveColor(ResourceResolver resources, ResourceValue color) {
        color = resources.resolveResValue(color);
        if (color == null) {
            return null;
        }
        String value = color.getValue();

        while (value != null) {
            if (value.startsWith("#")) { //$NON-NLS-1$
                try {
                    int rgba = ImageUtils.getColor(value);
                    // Drop alpha channel
                    return ImageUtils.intToRgb(rgba);
                } catch (NumberFormatException nfe) {
                    // Pass
                }
                return null;
            }
            if (value.startsWith(PREFIX_RESOURCE_REF)) {
                boolean isFramework = color.isFramework();
                color = resources.findResValue(value, isFramework);
                if (color != null) {
                    value = color.getValue();
                } else {
                    break;
                }
            } else {
                File file = new File(value);
                if (file.exists() && file.getName().endsWith(DOT_XML)) {
                    // Parse
                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    BufferedInputStream bis = null;
                    try {
                        bis = new BufferedInputStream(new FileInputStream(file));
                        InputSource is = new InputSource(bis);
                        factory.setNamespaceAware(true);
                        factory.setValidating(false);
                        DocumentBuilder builder = factory.newDocumentBuilder();
                        Document document = builder.parse(is);
                        NodeList items = document.getElementsByTagName(TAG_ITEM);

                        value = findColorValue(items);
                        continue;
                    } catch (Exception e) {
                        AdtPlugin.log(e, "Failed parsing color file %1$s", file.getName());
                    } finally {
                        if (bis != null) {
                            try {
                                bis.close();
                            } catch (IOException e) {
                                // Nothing useful can be done here
                            }
                        }
                    }
                }

                return null;
            }
        }

        return null;
    }

    /**
     * Searches a color XML file for the color definition element that does not
     * have an associated state and returns its color
     */
    private static String findColorValue(NodeList items) {
        for (int i = 0, n = items.getLength(); i < n; i++) {
            // Find non-state color definition
            Node item = items.item(i);
            boolean hasState = false;
            if (item.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) item;
                if (element.hasAttributeNS(ANDROID_URI, ATTR_COLOR)) {
                    NamedNodeMap attributes = element.getAttributes();
                    for (int j = 0, m = attributes.getLength(); j < m; j++) {
                        Attr attribute = (Attr) attributes.item(j);
                        if (attribute.getLocalName().startsWith("state_")) { //$NON-NLS-1$
                            hasState = true;
                            break;
                        }
                    }

                    if (!hasState) {
                        return element.getAttributeNS(ANDROID_URI, ATTR_COLOR);
                    }
                }
            }
        }

        return null;
    }
}
