/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.tools.lint.checks;

import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.APP_PREFIX;
import static com.android.SdkConstants.AUTO_URI;
import static com.android.SdkConstants.TOOLS_PREFIX;
import static com.android.SdkConstants.TOOLS_URI;
import static com.android.SdkConstants.URI_PREFIX;
import static com.android.SdkConstants.XMLNS_PREFIX;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.tools.lint.detector.api.Category;
import com.android.tools.lint.detector.api.Implementation;
import com.android.tools.lint.detector.api.Issue;
import com.android.tools.lint.detector.api.LayoutDetector;
import com.android.tools.lint.detector.api.LintUtils;
import com.android.tools.lint.detector.api.Project;
import com.android.tools.lint.detector.api.Scope;
import com.android.tools.lint.detector.api.Severity;
import com.android.tools.lint.detector.api.Speed;
import com.android.tools.lint.detector.api.XmlContext;

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 java.util.HashMap;
import java.util.Map;

/**
 * Checks for various issues related to XML namespaces
 */
public class NamespaceDetector extends LayoutDetector {

    @SuppressWarnings("unchecked")
    private static final Implementation IMPLEMENTATION = new Implementation(
            NamespaceDetector.class,
            Scope.MANIFEST_AND_RESOURCE_SCOPE,
            Scope.RESOURCE_FILE_SCOPE, Scope.MANIFEST_SCOPE);

    /** Typos in the namespace */
    public static final Issue TYPO = Issue.create(
            "NamespaceTypo", //$NON-NLS-1$
            "Misspelled namespace declaration",

            "Accidental misspellings in namespace declarations can lead to some very " +
            "obscure error messages. This check looks for potential misspellings to " +
            "help track these down.",
            Category.CORRECTNESS,
            8,
            Severity.FATAL,
            IMPLEMENTATION);

    /** Unused namespace declarations */
    public static final Issue UNUSED = Issue.create(
            "UnusedNamespace", //$NON-NLS-1$
            "Unused namespace",

            "Unused namespace declarations take up space and require processing that is not " +
            "necessary",

            Category.PERFORMANCE,
            1,
            Severity.WARNING,
            IMPLEMENTATION);

    /** Using custom namespace attributes in a library project */
    public static final Issue CUSTOM_VIEW = Issue.create(
            "LibraryCustomView", //$NON-NLS-1$
            "Custom views in libraries should use res-auto-namespace",

            "When using a custom view with custom attributes in a library project, the layout " +
            "must use the special namespace " + AUTO_URI + " instead of a URI which includes " +
            "the library project's own package. This will be used to automatically adjust the " +
            "namespace of the attributes when the library resources are merged into the " +
            "application project.",
            Category.CORRECTNESS,
            6,
            Severity.FATAL,
            IMPLEMENTATION);

    /** Unused namespace declarations */
    public static final Issue RES_AUTO = Issue.create(
            "ResAuto", //$NON-NLS-1$
            "Hardcoded Package in Namespace",

            "In Gradle projects, the actual package used in the final APK can vary; for example," +
            "you can add a `.debug` package suffix in one version and not the other. " +
            "Therefore, you should *not* hardcode the application package in the resource; " +
            "instead, use the special namespace `http://schemas.android.com/apk/res-auto` " +
            "which will cause the tools to figure out the right namespace for the resource " +
            "regardless of the actual package used during the build.",

            Category.CORRECTNESS,
            9,
            Severity.FATAL,
            IMPLEMENTATION);

    /** Prefix relevant for custom namespaces */
    private static final String XMLNS_ANDROID = "xmlns:android";                    //$NON-NLS-1$
    private static final String XMLNS_A = "xmlns:a";                                //$NON-NLS-1$

    private Map<String, Attr> mUnusedNamespaces;
    private boolean mCheckUnused;

    /** Constructs a new {@link NamespaceDetector} */
    public NamespaceDetector() {
    }

    @NonNull
    @Override
    public Speed getSpeed() {
        return Speed.FAST;
    }

    @Override
    public void visitDocument(@NonNull XmlContext context, @NonNull Document document) {
        boolean haveCustomNamespace = false;
        Element root = document.getDocumentElement();
        NamedNodeMap attributes = root.getAttributes();
        for (int i = 0, n = attributes.getLength(); i < n; i++) {
            Node item = attributes.item(i);
            String prefix = item.getNodeName();
            if (prefix.startsWith(XMLNS_PREFIX)) {
                String value = item.getNodeValue();

                if (!value.equals(ANDROID_URI)) {
                    Attr attribute = (Attr) item;

                    if (value.startsWith(URI_PREFIX)) {
                        haveCustomNamespace = true;
                        if (mUnusedNamespaces == null) {
                            mUnusedNamespaces = new HashMap<String, Attr>();
                        }
                        mUnusedNamespaces.put(prefix.substring(XMLNS_PREFIX.length()),
                                attribute);
                    } else if (value.startsWith("urn:")) { //$NON-NLS-1$
                        continue;
                    } else if (!value.startsWith("http://")) { //$NON-NLS-1$
                        if (context.isEnabled(TYPO)) {
                            context.report(TYPO, attribute, context.getValueLocation(attribute),
                                    "Suspicious namespace: should start with `http://`");
                        }

                        continue;
                    } else if (!value.equals(AUTO_URI) && value.contains("auto") && //$NON-NLS-1$
                            value.startsWith("http://schemas.android.com/")) { //$NON-NLS-1$
                        context.report(RES_AUTO, attribute, context.getValueLocation(attribute),
                                "Suspicious namespace: Did you mean `" + AUTO_URI + "`?");
                    } else if (value.equals(TOOLS_URI) && (prefix.equals(XMLNS_ANDROID) ||
                            prefix.endsWith(APP_PREFIX) && prefix.equals(
                                    XMLNS_PREFIX + APP_PREFIX))) {
                        context.report(TYPO, attribute, context.getValueLocation(attribute),
                                "Suspicious namespace and prefix combination");
                    }

                    if (!context.isEnabled(TYPO)) {
                        continue;
                    }

                    String name = attribute.getName();
                    if (!name.equals(XMLNS_ANDROID) && !name.equals(XMLNS_A)) {
                        // See if it looks like a typo
                        int resIndex = value.indexOf("/res/"); //$NON-NLS-1$
                        if (resIndex != -1 && value.length() + 5 > URI_PREFIX.length()) {
                            String urlPrefix = value.substring(0, resIndex + 5);
                            if (!urlPrefix.equals(URI_PREFIX) &&
                                    LintUtils.editDistance(URI_PREFIX, urlPrefix) <= 3) {
                                String correctUri = URI_PREFIX + value.substring(resIndex + 5);
                                context.report(TYPO, attribute,
                                        context.getValueLocation(attribute),
                                        String.format(
                                            "Possible typo in URL: was `\"%1$s\"`, should " +
                                            "probably be `\"%2$s\"`",
                                            value, correctUri));
                            }
                        }
                        continue;
                    }

                    if (name.equals(XMLNS_A)) {
                        // For the "android" prefix we always assume that the namespace prefix
                        // should be our expected prefix, but for the "a" prefix we make sure
                        // that it's at least "close"; if you're bound it to something completely
                        // different, don't complain.
                        if (LintUtils.editDistance(ANDROID_URI, value) > 4) {
                            continue;
                        }
                    }

                    if (value.equalsIgnoreCase(ANDROID_URI)) {
                        context.report(TYPO, attribute, context.getValueLocation(attribute),
                                String.format(
                                    "URI is case sensitive: was `\"%1$s\"`, expected `\"%2$s\"`",
                                    value, ANDROID_URI));
                    } else {
                        context.report(TYPO, attribute, context.getValueLocation(attribute),
                                String.format(
                                    "Unexpected namespace URI bound to the `\"android\"` " +
                                    "prefix, was `%1$s`, expected `%2$s`", value, ANDROID_URI));
                    }
                } else if (!prefix.equals(XMLNS_ANDROID) &&
                        ((prefix.endsWith(TOOLS_PREFIX) && prefix.equals(XMLNS_PREFIX + TOOLS_PREFIX)) ||
                        (prefix.endsWith(APP_PREFIX) && prefix.equals(XMLNS_PREFIX + APP_PREFIX)))) {
                    Attr attribute = (Attr) item;
                    context.report(TYPO, attribute, context.getValueLocation(attribute),
                            "Suspicious namespace and prefix combination");
                }
            }
        }

        if (haveCustomNamespace) {
            Project project = context.getProject();
            boolean checkCustomAttrs =
                    context.isEnabled(CUSTOM_VIEW) && project.isLibrary()
                    || context.isEnabled(RES_AUTO) && project.isGradleProject();

            mCheckUnused = context.isEnabled(UNUSED);

            if (checkCustomAttrs) {
                checkCustomNamespace(context, root);
            }
            checkElement(root);

            if (mCheckUnused && !mUnusedNamespaces.isEmpty()) {
                for (Map.Entry<String, Attr> entry : mUnusedNamespaces.entrySet()) {
                    String prefix = entry.getKey();
                    Attr attribute = entry.getValue();
                    context.report(UNUSED, attribute, context.getLocation(attribute),
                            String.format("Unused namespace `%1$s`", prefix));
                }
            }
        }
    }

    private static void checkCustomNamespace(XmlContext context, Element element) {
        NamedNodeMap attributes = element.getAttributes();
        for (int i = 0, n = attributes.getLength(); i < n; i++) {
            Attr attribute = (Attr) attributes.item(i);
            if (attribute.getName().startsWith(XMLNS_PREFIX)) {
                String uri = attribute.getValue();
                if (uri != null && !uri.isEmpty() && uri.startsWith(URI_PREFIX)
                        && !uri.equals(ANDROID_URI)) {
                    if (context.getProject().isGradleProject()) {
                        context.report(RES_AUTO, attribute, context.getValueLocation(attribute),
                            "In Gradle projects, always use `" + AUTO_URI + "` for custom " +
                            "attributes");
                    } else {
                        context.report(CUSTOM_VIEW, attribute, context.getValueLocation(attribute),
                            "When using a custom namespace attribute in a library project, " +
                            "use the namespace `\"" + AUTO_URI + "\"` instead.");
                    }
                }
            }
        }
    }

    private void checkElement(Node node) {
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            if (mCheckUnused) {
                NamedNodeMap attributes = node.getAttributes();
                for (int i = 0, n = attributes.getLength(); i < n; i++) {
                    Attr attribute = (Attr) attributes.item(i);
                    String prefix = attribute.getPrefix();
                    if (prefix != null) {
                        mUnusedNamespaces.remove(prefix);
                    }
                }
            }

            NodeList childNodes = node.getChildNodes();
            for (int i = 0, n = childNodes.getLength(); i < n; i++) {
                checkElement(childNodes.item(i));
            }
        }
    }
}
