/*
 * Copyright (C) 2013 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.client.api

import com.android.SdkConstants
import com.android.SdkConstants.DOT_CLASS
import com.android.tools.lint.detector.api.CURRENT_API
import com.android.tools.lint.detector.api.Issue
import com.android.tools.lint.detector.api.Project
import com.android.tools.lint.detector.api.Severity
import com.android.tools.lint.detector.api.describeApi
import com.android.utils.SdkUtils
import java.io.File
import java.io.IOException
import java.io.InputStreamReader
import java.lang.ref.SoftReference
import java.net.URLClassLoader
import java.util.HashMap
import java.util.jar.Attributes
import java.util.jar.JarFile

/**
 *  An [IssueRegistry] for a custom lint rule jar file. The rule jar should provide a
 * manifest entry with the key `Lint-Registry` and the value of the fully qualified name of an
 * implementation of [IssueRegistry] (with a default constructor).
 *
 *  NOTE: The custom issue registry should not extend this file; it should be a plain
 * IssueRegistry! This file is used internally to wrap the given issue registry.
 */
class JarFileIssueRegistry
private constructor(
    client: LintClient,
    /** The jar file the rules were loaded from */
    val jarFile: File,
    /** The custom lint check's issue registry that this [JarFileIssueRegistry] wraps */
    registry: IssueRegistry
) : IssueRegistry() {

    override val issues: List<Issue> = registry.issues.toList()
    private var timestamp: Long = jarFile.lastModified()

    override val isUpToDate: Boolean
        get() = timestamp == jarFile.lastModified()

    init {
        val loader = registry.javaClass.classLoader
        if (loader is URLClassLoader) {
            loadAndCloseURLClassLoader(client, jarFile, loader)
        }
    }

    override val api: Int = com.android.tools.lint.detector.api.CURRENT_API

    companion object Factory {
        /** Service key for automatic discovery of lint rules */
        private const val SERVICE_KEY =
            "META-INF/services/com.android.tools.lint.client.api.IssueRegistry"

        /**
         * Manifest constant for declaring an issue provider.
         *
         * Example: Lint-Registry-v2: foo.bar.CustomIssueRegistry
         */
        private const val MF_LINT_REGISTRY = "Lint-Registry-v2"

        /** Older key: these are for older custom rules */
        private const val MF_LINT_REGISTRY_OLD = "Lint-Registry"

        /** Cache of custom lint check issue registries */
        private var cache: MutableMap<File, SoftReference<JarFileIssueRegistry>>? = null

        /**
         * Loads custom rules from the given list of jar files and returns a list
         * of [JarFileIssueRegistry} instances.
         *
         * It will also deduplicate issue registries, since in Gradle projects with
         * local lint.jar's it's possible for the same lint.jar to be handed back
         * multiple times with different paths through various separate dependencies.
         */
        fun get(
            client: LintClient,
            jarFiles: Collection<File>,
            currentProject: Project?
        ): List<JarFileIssueRegistry> {
            val registryMap = try {
                findRegistries(client, jarFiles)
            } catch (e: IOException) {
                client.log(e, "Could not load custom lint check jar files: ${e.message}")
                return emptyList()
            }

            if (registryMap.isEmpty()) {
                return emptyList()
            }

            val capacity = jarFiles.size + 1
            val registries = ArrayList<JarFileIssueRegistry>(capacity)

            for ((registryClass, jarFile) in registryMap) {
                try {
                    val registry = get(client, registryClass, jarFile, currentProject) ?: continue
                    registries.add(registry)
                } catch (e: Throwable) {
                    client.log(e, "Could not load custom lint check jar file %1\$s", jarFile)
                }
            }

            return registries
        }

        /**
         * Returns a [JarFileIssueRegistry] for the given issue registry class name
         * and jar file, with caching
         */
        private fun get(
            client: LintClient,
            registryClassName: String,
            jarFile: File,
            currentProject: Project?
        ):
                JarFileIssueRegistry? {
            if (cache == null) {
                cache = HashMap()
            } else {
                val reference = cache!![jarFile]
                if (reference != null) {
                    val registry = reference.get()
                    if (registry != null && registry.isUpToDate) {
                        return registry
                    }
                }
            }

            // Ensure that the scope-to-detector map doesn't return stale results
            IssueRegistry.reset()

            val userRegistry = loadIssueRegistry(
                client, jarFile, registryClassName,
                currentProject
            )
            return if (userRegistry != null) {
                val jarIssueRegistry = JarFileIssueRegistry(client, jarFile, userRegistry)
                cache!![jarFile] = SoftReference(jarIssueRegistry)
                jarIssueRegistry
            } else {
                null
            }
        }

        /** Combine one or more issue registries into a single one */
        fun join(vararg registries: IssueRegistry): IssueRegistry {
            return if (registries.size == 1) {
                registries[0]
            } else {
                CompositeIssueRegistry(registries.toList())
            }
        }

        /**
         * Given a jar file, create a class loader for it and instantiate
         * the named issue registry.
         *
         * TODO: Add a custom class loader architecture here such that
         * custom rules can have dependent jars without needing to jar-jar them!
         */
        private fun loadIssueRegistry(
            client: LintClient,
            jarFile: File,
            className: String,
            currentProject: Project?
        ): IssueRegistry? {
            // Make a class loader for this jar
            val url = SdkUtils.fileToUrl(jarFile)
            return try {
                val loader = client.createUrlClassLoader(
                    arrayOf(url),
                    JarFileIssueRegistry::class.java.classLoader
                )
                val registryClass = Class.forName(className, true, loader)
                val registry = registryClass.newInstance() as IssueRegistry

                val issues = try {
                    registry.issues
                } catch (e: Throwable) {
                    val stacktrace = StringBuilder()
                    LintDriver.appendStackTraceSummary(e, stacktrace)
                    val message = "Lint found one or more custom checks that could not " +
                            "be loaded. The most likely reason for this is that it is using an " +
                            "older, incompatible or unsupported API in lint. Make sure these " +
                            "lint checks are updated to the new APIs. The issue registry class " +
                            "is $className. The class loading issue is ${e.message}: $stacktrace"

                    LintClient.report(
                        client = client, issue = OBSOLETE_LINT_CHECK,
                        message = message, file = jarFile, project = currentProject
                    )
                    return null
                }

                try {
                    val apiField = registryClass.getDeclaredMethod("getApi")
                    val api = apiField.invoke(registry) as Int
                    if (api < CURRENT_API) {
                        val message = "Lint found an issue registry (`$className`) which is " +
                                "older than the current API level; these checks may not work " +
                                "correctly.\n" +
                                "\n" +
                                "Recompile the checks against the latest version. " +
                                "Custom check API version is $api (${describeApi(api)}), " +
                                "current lint API level is $CURRENT_API " +
                                "(${describeApi(CURRENT_API)})"
                        LintClient.report(
                            client = client, issue = OBSOLETE_LINT_CHECK,
                            message = message, file = jarFile, project = currentProject
                        )
                        // Not returning here: try to run the checks
                    } else {
                        try {
                            val minApi = registry.minApi
                            if (minApi > CURRENT_API) {
                                val message = "Lint found an issue registry (`$className`) which " +
                                        "requires a newer API level. That means that the custom " +
                                        "lint checks are intended for a newer lint version; please " +
                                        "upgrade"
                                LintClient.report(
                                    client = client, issue = OBSOLETE_LINT_CHECK,
                                    message = message, file = jarFile, project = currentProject
                                )
                                return null
                            }
                        } catch (ignore: Throwable) {
                        }
                    }
                } catch (e: Throwable) {
                    var message = "Lint found an issue registry (`$className`) which did not " +
                            "specify the Lint API version it was compiled with.\n" +
                            "\n" +
                            "**This means that the lint checks are likely not compatible.**\n" +
                            "\n" +
                            "If you are the author of this lint check, make your lint " +
                            "`IssueRegistry` class contain\n" +
                            "\u00a0\u00a0override val api: Int = com.android.tools.lint.detector.api.CURRENT_API\n" +
                            "or from Java,\n" +
                            "\u00a0\u00a0@Override public int getApi() { return com.android.tools.lint.detector.api.ApiKt.CURRENT_API; }"

                    val issueIds = issues.map { it.id }.sorted()
                    if (issueIds.any()) {
                        message += ("\n" +
                                "\n" +
                                "If you are just using lint checks from a third party library " +
                                "you have no control over, you can disable these lint checks (if " +
                                "they misbehave) like this:\n" +
                                "\n" +
                                "    android {\n" +
                                "        lintOptions {\n" +
                                "            disable ${issueIds.joinToString(
                                    separator = ",\n                    "
                                ) { "\"$it\"" }}\n" +
                                "        }\n" +
                                "    }\n").replace(
                            // Force indentation
                            "    ",
                            "\u00a0\u00a0\u00a0\u00a0"
                        )
                    }

                    LintClient.report(
                        client = client, issue = OBSOLETE_LINT_CHECK,
                        message = message, file = jarFile, project = currentProject
                    )
                    // Not returning here: try to run the checks
                }

                registry
            } catch (e: Throwable) {
                client.log(e, "Could not load custom lint check jar file %1\$s", jarFile)
                null
            }
        }

        /**
         * Returns a map from issue registry qualified name to the corresponding jar file
         * that contains it
         */
        private fun findRegistries(
            client: LintClient,
            jarFiles: Collection<File>
        ): Map<String, File> {
            val registryClassToJarFile = HashMap<String, File>()
            for (jarFile in jarFiles) {
                JarFile(jarFile).use { file ->
                    val manifest = file.manifest
                    val attrs = manifest.mainAttributes
                    var attribute: Any? = attrs[Attributes.Name(MF_LINT_REGISTRY)]
                    var isLegacy = false
                    if (attribute == null) {
                        attribute = attrs[Attributes.Name(MF_LINT_REGISTRY_OLD)]
                        if (attribute != null) {
                            isLegacy = true
                        }
                    }
                    if (attribute is String) {
                        val className = attribute

                        // Store class name -- but it may not be unique (there could be
                        // multiple separate jar files pointing to the same issue registry
                        // (due to the way local lint.jar files propagate via project
                        // dependencies) so only store this file if it hasn't already
                        // been found, or if it's a v2 version (e.g. not legacy)
                        if (!isLegacy || registryClassToJarFile[className] == null) {
                            registryClassToJarFile[className] = jarFile
                        }
                    } else {
                        // Load service keys. We're reading it manually instead of using
                        // ServiceLoader because we don't want to put these jars into
                        // the class loaders yet (since there can be many duplicates
                        // when a library is available through multiple dependencies)
                        val services = file.getJarEntry(SERVICE_KEY)
                        if (services != null) {
                            file.getInputStream(services).use {
                                val reader = InputStreamReader(it, Charsets.UTF_8)
                                reader.useLines {
                                    for (line in it) {
                                        val comment = line.indexOf("#")
                                        val className = if (comment >= 0) {
                                            line.substring(0, comment).trim()
                                        } else {
                                            line.trim()
                                        }
                                        if (!className.isEmpty() &&
                                            registryClassToJarFile[className] == null
                                        ) {
                                            registryClassToJarFile[className] = jarFile
                                        }
                                    }
                                }
                            }
                            return registryClassToJarFile
                        }

                        client.log(
                            Severity.ERROR, null,
                            "Custom lint rule jar %1\$s does not contain a valid " +
                                    "registry manifest key (%2\$s).\n" +
                                    "Either the custom jar is invalid, or it uses an outdated " +
                                    "API not supported this lint client",
                            jarFile.path, MF_LINT_REGISTRY
                        )
                    }
                }
            }

            return registryClassToJarFile
        }

        /**
         * Work around http://bugs.java.com/bugdatabase/view_bug.do?bug_id=5041014 :
         * URLClassLoader, on Windows, locks the .jar file forever.
         * As of Java 7, there's a workaround: you can call close() when you're "done"
         * with the file. We'll do that here. However, the whole point of the
         * [JarFileIssueRegistry] is that when lint is run over and over again
         * as the user is editing in the IDE and we're background checking the code, we
         * don't want to keep loading the custom view classes over and over again: we want to
         * cache them. Therefore, just closing the URLClassLoader right away isn't great
         * either. However, it turns out it's safe to close the URLClassLoader once you've
         * loaded the classes you need, since the URLClassLoader will continue to serve
         * those classes even after its close() methods has been called.
         *
         * Therefore, if we can call close() on this URLClassLoader, we'll proactively load
         * all class files we find in the .jar file, then close it.
         *
         * @param client the client to report errors to
         * @param file the .jar file
         * @param loader the URLClassLoader we should close
         */
        private fun loadAndCloseURLClassLoader(
            client: LintClient,
            file: File,
            loader: URLClassLoader
        ) {
            if (SdkConstants.CURRENT_PLATFORM != SdkConstants.PLATFORM_WINDOWS) {
                // We don't need to close the class loader on other platforms than Windows
                return
            }

            // Before closing the jar file, proactively load all classes:
            try {
                JarFile(file).use { jar ->
                    val enumeration = jar.entries()
                    while (enumeration.hasMoreElements()) {
                        val entry = enumeration.nextElement()
                        val path = entry.name
                        // Load non-inner-classes
                        if (path.endsWith(DOT_CLASS) && path.indexOf('$') == -1) {
                            // Strip .class suffix and change .jar file path (/)
                            // to class name (.'s).
                            val name = path.substring(0, path.length - DOT_CLASS.length)
                                .replace('/', '.')
                            try {
                                val cls = Class.forName(name, true, loader)
                                // Actually, initialize them too to make sure basic classes
                                // needed by the detector are available
                                if (!(cls.isAnnotation || cls.isEnum || cls.isInterface)) {
                                    try {
                                        val defaultConstructor = cls.getConstructor()
                                        defaultConstructor.isAccessible = true
                                        defaultConstructor.newInstance()
                                    } catch (ignore: NoSuchMethodException) {
                                    }
                                }
                            } catch (e: Throwable) {
                                client.log(
                                    Severity.ERROR, e,
                                    "Failed to prefetch $name from $file"
                                )
                            }
                        }
                    }
                }
            } catch (ignore: Throwable) {
            } finally {
                // Finally close the URL class loader
                try {
                    loader.close()
                } catch (ignore: Throwable) {
                    // Couldn't close. This is unlikely.
                }
            }
        }
    }
}
