/*
 * 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 com.android.SdkConstants.ANDROID_URI
import com.android.SdkConstants.APP_PREFIX
import com.android.SdkConstants.AUTO_URI
import com.android.SdkConstants.TOOLS_PREFIX
import com.android.SdkConstants.TOOLS_URI
import com.android.SdkConstants.URI_PREFIX
import com.android.SdkConstants.XMLNS_ANDROID
import com.android.SdkConstants.XMLNS_PREFIX
import com.android.ide.common.rendering.api.ResourceNamespace
import com.android.resources.ResourceFolderType
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.LintFix
import com.android.tools.lint.detector.api.ResourceXmlDetector
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.XmlContext
import com.android.tools.lint.detector.api.isEditableTo
import com.android.utils.XmlUtils.getFirstSubTag
import com.android.utils.XmlUtils.getNextTag
import org.w3c.dom.Attr
import org.w3c.dom.Document
import org.w3c.dom.Element
import java.util.HashMap

/** Checks for various issues related to XML namespaces  */
/** Constructs a new [NamespaceDetector]  */
class NamespaceDetector : ResourceXmlDetector() {

    private var unusedNamespaces: MutableMap<String, Attr>? = null

    override fun visitDocument(context: XmlContext, document: Document) {
        var haveCustomNamespace = false
        val root = document.documentElement
        val attributes = root.attributes
        val n = attributes.length
        for (i in 0 until n) {
            val item = attributes.item(i)
            val prefix = item.nodeName
            if (prefix.startsWith(XMLNS_PREFIX)) {
                val value = item.nodeValue

                if (value != ANDROID_URI) {
                    val attribute = item as Attr

                    if (value.startsWith(URI_PREFIX)) {
                        haveCustomNamespace = true
                        val namespaces = unusedNamespaces ?: run {
                            val new = HashMap<String, Attr>()
                            unusedNamespaces = new
                            new
                        }
                        namespaces[prefix.substring(XMLNS_PREFIX.length)] = attribute
                    } else if (value.startsWith("urn:")) {
                        continue
                    } else if (!value.startsWith("http://")) {
                        if (context.isEnabled(TYPO) &&
                            // In XML there can be random XML documents from users
                            // with arbitrary schemas; let them use https if they want
                            context.resourceFolderType != ResourceFolderType.XML
                        ) {
                            var fix: LintFix? = null
                            if (value.startsWith("https://")) {
                                fix = LintFix.create()
                                    .replace()
                                    .text("https")
                                    .with("http")
                                    .name("Replace with http://${value.substring(8)}")
                                    .build()
                            }
                            context.report(
                                TYPO,
                                attribute,
                                context.getValueLocation(attribute),
                                //noinspection LintImplUnexpectedDomain
                                "Suspicious namespace: should start with `http://`",
                                fix
                            )
                        }
                        continue
                    } else if (value != AUTO_URI &&
                        value.contains("auto") &&
                        value.startsWith("http://schemas.android.com/")
                    ) {
                        context.report(
                            RES_AUTO,
                            attribute,
                            context.getValueLocation(attribute),
                            "Suspicious namespace: Did you mean `$AUTO_URI`?"
                        )
                    } else if (value == TOOLS_URI && (prefix == XMLNS_ANDROID || prefix.endsWith(
                            APP_PREFIX
                        ) && prefix == XMLNS_PREFIX + APP_PREFIX)
                    ) {
                        context.report(
                            TYPO,
                            attribute,
                            context.getValueLocation(attribute),
                            "Suspicious namespace and prefix combination"
                        )
                    }

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

                    val name = attribute.name
                    if (name != XMLNS_ANDROID && name != XMLNS_A) {
                        // See if it looks like a typo
                        val resIndex = value.indexOf("/res/")
                        if (resIndex != -1 && value.length + 5 > URI_PREFIX.length) {
                            val urlPrefix = value.substring(0, resIndex + 5)
                            if (urlPrefix != URI_PREFIX && isEditableTo(URI_PREFIX, urlPrefix, 3)) {
                                val correctUri = URI_PREFIX + value.substring(resIndex + 5)
                                context.report(
                                    TYPO,
                                    attribute,
                                    context.getValueLocation(attribute),
                                    "Possible typo in URL: was `\"$value\"`, should " +
                                            "probably be `\"$correctUri\"`"
                                )
                            }
                        }
                        continue
                    }

                    if (name == 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 (!isEditableTo(ANDROID_URI, value, 4)) {
                            continue
                        }
                    }

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

        if (haveCustomNamespace) {
            val project = context.project
            val checkCustomAttrs =
                project.resourceNamespace == ResourceNamespace.RES_AUTO && (context.isEnabled(
                    CUSTOM_VIEW
                ) && project.isLibrary || context.isEnabled(RES_AUTO) && project.isGradleProject)

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

            val checkUnused = context.isEnabled(UNUSED)
            if (checkUnused) {
                checkUnused(root)
                val namespaces = unusedNamespaces
                if (namespaces != null && !namespaces.isEmpty()) {
                    for ((prefix, attribute) in namespaces) {
                        context.report(
                            UNUSED,
                            attribute,
                            context.getLocation(attribute),
                            "Unused namespace `$prefix`"
                        )
                    }
                }
            }
        }

        if (context.isEnabled(REDUNDANT)) {
            var child = getFirstSubTag(root)
            while (child != null) {
                checkRedundant(context, child)
                child = getNextTag(child)
            }
        }
    }

    private fun checkUnused(element: Element) {
        val attributes = element.attributes
        val n = attributes.length
        for (i in 0 until n) {
            val attribute = attributes.item(i) as Attr
            val prefix = attribute.prefix
            if (prefix != null) {
                unusedNamespaces?.remove(prefix)
            }
        }

        var child = getFirstSubTag(element)
        while (child != null) {
            checkUnused(child)
            child = getNextTag(child)
        }
    }

    private fun checkRedundant(context: XmlContext, element: Element) {
        // This method will not be called on the document element

        val attributes = element.attributes
        val n = attributes.length
        for (i in 0 until n) {
            val attribute = attributes.item(i) as Attr
            val name = attribute.name
            if (name.startsWith(XMLNS_PREFIX)) {
                // See if this attribute is already set on the document element
                val root = element.ownerDocument.documentElement
                val redundant = root.getAttribute(name) == attribute.value
                if (redundant) {

                    val fix =
                        fix().name("Delete namespace").set().remove(name).build()
                    context.report(
                        REDUNDANT, attribute, context.getLocation(attribute),
                        "This namespace declaration is redundant", fix
                    )
                }
            }
        }

        var child = getFirstSubTag(element)
        while (child != null) {
            checkRedundant(context, child)
            child = getNextTag(child)
        }
    }

    private fun checkCustomNamespace(context: XmlContext, element: Element) {
        val attributes = element.attributes
        val n = attributes.length
        for (i in 0 until n) {
            val attribute = attributes.item(i) as Attr
            if (attribute.name.startsWith(XMLNS_PREFIX)) {
                val uri = attribute.value
                if (uri != null &&
                    !uri.isEmpty() &&
                    uri.startsWith(URI_PREFIX) &&
                    uri != ANDROID_URI
                ) {
                    if (context.project.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"
                        )
                    }
                }
            }
        }
    }

    companion object {
        private val IMPLEMENTATION = Implementation(
            NamespaceDetector::class.java,
            Scope.MANIFEST_AND_RESOURCE_SCOPE,
            Scope.RESOURCE_FILE_SCOPE,
            Scope.MANIFEST_SCOPE
        )

        /** Typos in the namespace */
        @JvmField
        val TYPO = Issue.create(
            id = "NamespaceTypo",
            briefDescription = "Misspelled namespace declaration",
            explanation = """
                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 = Category.CORRECTNESS,
            priority = 8,
            severity = Severity.FATAL,
            implementation = IMPLEMENTATION
        )

        /** Unused namespace declarations */
        @JvmField
        val UNUSED = Issue.create(
            id = "UnusedNamespace",
            briefDescription = "Unused namespace",
            explanation = """
                Unused namespace declarations take up space and require processing that is \
                not necessary""",
            category = Category.PERFORMANCE,
            priority = 1,
            severity = Severity.WARNING,
            implementation = IMPLEMENTATION
        )

        /** Unused namespace declarations */
        @JvmField
        val REDUNDANT = Issue.create(
            id = "RedundantNamespace",
            briefDescription = "Redundant namespace",
            explanation = """
                In Android XML documents, only specify the namespace on the root/document \
                element. Namespace declarations elsewhere in the document are typically \
                accidental leftovers from copy/pasting XML from other files or documentation.""",
            category = Category.PERFORMANCE,
            priority = 1,
            severity = Severity.WARNING,
            implementation = IMPLEMENTATION
        )

        /** Using custom namespace attributes in a library project */
        @JvmField
        val CUSTOM_VIEW = Issue.create(
            id = "LibraryCustomView",
            briefDescription = "Custom views in libraries should use res-auto-namespace",
            explanation = """
                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 = Category.CORRECTNESS,
            priority = 6,
            severity = Severity.FATAL,
            implementation = IMPLEMENTATION
        )

        /** Unused namespace declarations */
        @JvmField
        val RES_AUTO = Issue.create(
            id = "ResAuto",
            briefDescription = "Hardcoded Package in Namespace",
            explanation = """
                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 = Category.CORRECTNESS,
            priority = 9,
            severity = Severity.FATAL,
            implementation = IMPLEMENTATION
        )

        private const val XMLNS_A = "xmlns:a"
    }
}
