/*
 * Copyright (C) 2011 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.ABSOLUTE_LAYOUT
import com.android.SdkConstants.ANDROID_URI
import com.android.SdkConstants.ATTR_AUTO_TEXT
import com.android.SdkConstants.ATTR_CAPITALIZE
import com.android.SdkConstants.ATTR_EDITABLE
import com.android.SdkConstants.ATTR_INPUT_METHOD
import com.android.SdkConstants.ATTR_NUMERIC
import com.android.SdkConstants.ATTR_PASSWORD
import com.android.SdkConstants.ATTR_PERMISSION
import com.android.SdkConstants.ATTR_PHONE_NUMBER
import com.android.SdkConstants.ATTR_SINGLE_LINE
import com.android.SdkConstants.CLASS_PREFERENCE
import com.android.SdkConstants.EDIT_TEXT
import com.android.SdkConstants.TAG_SERVICE
import com.android.SdkConstants.TAG_USES_PERMISSION_SDK_23
import com.android.SdkConstants.TAG_USES_PERMISSION_SDK_M
import com.android.SdkConstants.VALUE_FALSE
import com.android.SdkConstants.VALUE_TRUE
import com.android.resources.ResourceFolderType
import com.android.resources.ResourceFolderType.LAYOUT
import com.android.resources.ResourceFolderType.XML
import com.android.tools.lint.detector.api.Category
import com.android.tools.lint.detector.api.Implementation
import com.android.tools.lint.detector.api.Incident
import com.android.tools.lint.detector.api.Issue.Companion.create
import com.android.tools.lint.detector.api.JavaContext
import com.android.tools.lint.detector.api.ResourceXmlDetector
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Scope.Companion.JAVA_FILE_SCOPE
import com.android.tools.lint.detector.api.Scope.Companion.MANIFEST_SCOPE
import com.android.tools.lint.detector.api.Scope.Companion.RESOURCE_FILE_SCOPE
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.SourceCodeScanner
import com.android.tools.lint.detector.api.XmlContext
import com.android.tools.lint.detector.api.minSdkAtLeast
import com.intellij.psi.PsiMethod
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UClass
import org.w3c.dom.Attr
import org.w3c.dom.Document
import org.w3c.dom.Element
import java.util.EnumSet

/** Check which looks for usage of deprecated tags, attributes, etc. */
class DeprecationDetector : ResourceXmlDetector(), SourceCodeScanner {

    // XML (resource and manifest) checks:

    override fun appliesTo(folderType: ResourceFolderType): Boolean {
        return folderType == LAYOUT || folderType == XML
    }

    override fun visitDocument(context: XmlContext, document: Document) {
        if (context.resourceFolderType == XML) {
            val rootElement = document.documentElement
            val tagName = rootElement.tagName
            if (tagName.startsWith("android.preference.")) {
                context.report(
                    ISSUE,
                    rootElement,
                    context.getNameLocation(rootElement),
                    "The `android.preference` library is deprecated, it is " +
                        "recommended that you migrate to the AndroidX Preference " +
                        "library instead."
                )
                return
            }
            if (tagName.startsWith("androidx.preference.")) {
                // Qualified androidx preference tags can skip inheritance checking.
                return
            }
            val parser = context.client.getUastParser(context.project)
            val tagClass = parser.evaluator.findClass(rootElement.tagName) ?: return
            if (parser.evaluator.inheritsFrom(tagClass, CLASS_PREFERENCE, false)) {
                context.report(
                    ISSUE,
                    rootElement,
                    context.getNameLocation(rootElement),
                    "`$tagName` inherits from `android.preference.Preference` which is " +
                        "now deprecated, it is recommended that you migrate to the " +
                        "AndroidX Preference library."
                )
            }
        }
    }

    override fun getApplicableElements(): Collection<String> {
        return listOf(ABSOLUTE_LAYOUT, TAG_USES_PERMISSION_SDK_M)
    }

    override fun getApplicableAttributes(): Collection<String>? {
        return listOf(
            // TODO: fill_parent is deprecated as of API 8.
            // We could warn about it, but it will probably be very noisy
            // and make people disable the deprecation check; let's focus on
            // some older flags for now
            // "fill_parent",
            ATTR_EDITABLE,
            ATTR_INPUT_METHOD,
            ATTR_AUTO_TEXT,
            ATTR_CAPITALIZE,
            ATTR_NUMERIC,
            ATTR_PHONE_NUMBER,
            ATTR_PASSWORD,
            ATTR_PERMISSION
            // ATTR_SINGLE_LINE is marked deprecated, but (a) it's used a lot everywhere,
            // including in our own apps, and (b) replacing it with the suggested replacement
            // can lead to crashes; see issue 37137344
            // ATTR_ENABLED is marked deprecated in android.R.attr but apparently
            // using the suggested replacement of state_enabled doesn't work, see issue b/36943030
            // These attributes are also deprecated; not yet enabled until we
            // know the API level to apply the deprecation for:
            // "ignored as of ICS (but deprecated earlier)"
            // "fadingEdge",
            // "This attribute is not used by the Android operating system."
            // "restoreNeedsApplication",
            // "This will create a non-standard UI appearance, because the search bar UI is
            // changing to use only icons for its buttons."
            // "searchButtonText",
        )
    }

    override fun visitElement(context: XmlContext, element: Element) {
        val tagName = element.tagName
        var message = "`$tagName` is deprecated"
        if (TAG_USES_PERMISSION_SDK_M == tagName) {
            message += ": Use `$TAG_USES_PERMISSION_SDK_23 instead"
        }
        context.report(ISSUE, element, context.getNameLocation(element), message)
    }

    override fun visitAttribute(context: XmlContext, attribute: Attr) {
        if (ANDROID_URI != attribute.namespaceURI) {
            return
        }
        val name = attribute.localName
        val fix: String
        var minSdk = 1
        when (name) {
            ATTR_PERMISSION -> {
                if (TAG_SERVICE == attribute.ownerElement.tagName &&
                    CHOOSER_TARGET_SERVICE_PERM == attribute.value
                ) {
                    context.report(
                        ISSUE,
                        attribute,
                        context.getLocation(attribute),
                        "ChooserTargetService` is deprecated: Please see $SHARE_API_URL",
                        fix().url(SHARE_API_URL).build()
                    )
                }
                return
            }
            ATTR_EDITABLE -> {
                fix = if (EDIT_TEXT != attribute.ownerElement.tagName) {
                    "Use an `<EditText>` to make it editable"
                } else {
                    if (VALUE_TRUE == attribute.value) {
                        "`<EditText>` is already editable"
                    } else {
                        "Use `inputType` instead"
                    }
                }
            }
            ATTR_SINGLE_LINE -> {
                fix = if (VALUE_FALSE == attribute.value) {
                    "False is the default, so just remove the attribute"
                } else {
                    "Use `maxLines=\"1\"` instead"
                }
            }
            else -> {
                fix = "Use `inputType` instead"
                // The inputType attribute was introduced in API 3 so don't warn about
                // deprecation if targeting older platforms
                minSdk = 3
            }
        }
        val incident = Incident(
            ISSUE,
            attribute,
            context.getLocation(attribute),
            "`${attribute.name}` is deprecated: $fix"
        )
        context.report(incident, minSdkAtLeast(minSdk))
    }

    // Kotlin and Java deprecation checks:

    override fun getApplicableConstructorTypes(): List<String> {
        return listOf(FIREBASE_JOB_DISPATCHER_CLASS)
    }

    override fun visitConstructor(
        context: JavaContext,
        node: UCallExpression,
        constructor: PsiMethod
    ) {
        val url = "https://developer.android.com/topic/libraries/architecture/workmanager/migrating-fb"
        context.report(
            ISSUE,
            node,
            context.getCallLocation(node, includeReceiver = false, includeArguments = false),
            "Job scheduling with `FirebaseJobDispatcher` is deprecated: Use AndroidX `WorkManager` instead",
            fix().url(url).build()
        )
    }

    override fun getApplicableMethodNames(): List<String> {
        return listOf("getInstance")
    }

    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
        if (!context.evaluator.isMemberInClass(method, GCM_NETWORK_MANAGER_CLASS)) {
            return
        }
        val url = "https://developer.android.com/topic/libraries/architecture/workmanager/migrating-gcm"
        context.report(
            ISSUE,
            node,
            context.getCallLocation(node, includeReceiver = false, includeArguments = false),
            "Job scheduling with `GcmNetworkManager` is deprecated: Use AndroidX `WorkManager` instead",
            fix().url(url).build()
        )
    }

    override fun applicableSuperClasses(): List<String> {
        return listOf(CHOOSER_TARGET_SERVICE_CLASS)
    }

    override fun visitClass(context: JavaContext, declaration: UClass) {
        val location = context.getNameLocation(declaration)
        context.report(
            ISSUE,
            declaration,
            location,
            "`${declaration.name}` extends the deprecated `ChooserTargetService`: Use the Share API instead",
            fix().url(SHARE_API_URL).build()
        )
    }

    companion object {
        @Suppress("SpellCheckingInspection")
        private const val FIREBASE_JOB_DISPATCHER_CLASS =
            "com.firebase.jobdispatcher.FirebaseJobDispatcher"

        private const val GCM_NETWORK_MANAGER_CLASS =
            "com.google.android.gms.gcm.GcmNetworkManager"

        private const val CHOOSER_TARGET_SERVICE_CLASS =
            "android.service.chooser.ChooserTargetService"

        private const val CHOOSER_TARGET_SERVICE_PERM =
            "android.permission.BIND_CHOOSER_TARGET_SERVICE"

        private const val SHARE_API_URL =
            "https://developer.android.com/training/sharing/receive.html?source=studio#providing-direct-share-targets"

        /** Usage of deprecated views or attributes. */
        @JvmField
        val ISSUE = create(
            id = "Deprecated",
            briefDescription = "Using deprecated resources",
            explanation = """
                Deprecated views, attributes and so on are deprecated because there \
                is a better way to do something. Do it that new way. You've been warned.
                """,
            category = Category.CORRECTNESS,
            priority = 2,
            severity = Severity.WARNING,
            implementation = Implementation(
                DeprecationDetector::class.java,
                EnumSet.of(Scope.MANIFEST, Scope.RESOURCE_FILE, Scope.JAVA_FILE),
                MANIFEST_SCOPE,
                RESOURCE_FILE_SCOPE,
                JAVA_FILE_SCOPE
            )
        )
    }
}
