/*
 * Copyright (C) 2017 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.build.gradle.internal.errors

import com.android.build.gradle.internal.errors.DeprecationReporter.DeprecationTarget
import com.android.build.gradle.options.BooleanOption
import com.android.build.gradle.options.Option
import com.android.build.gradle.options.ProjectOptions
import com.android.build.gradle.options.StringOption
import com.android.builder.errors.EvalIssueReporter
import com.android.builder.errors.EvalIssueReporter.Severity
import com.android.builder.errors.EvalIssueReporter.Type
import java.io.File

class DeprecationReporterImpl(
        private val issueReporter: EvalIssueReporter,
        private val projectOptions: ProjectOptions,
        private val projectPath: String) : DeprecationReporter {

    private val suppressedOptionWarnings: Set<String> =
        projectOptions[StringOption.SUPPRESS_UNSUPPORTED_OPTION_WARNINGS]?.splitToSequence(',')?.toSet()
                ?: setOf()

    override fun reportDeprecatedUsage(
            newDslElement: String,
            oldDslElement: String,
            deprecationTarget: DeprecationTarget) {
        issueReporter.reportIssue(
                Type.DEPRECATED_DSL,
                Severity.WARNING,
                "DSL element '$oldDslElement' is obsolete and has been replaced with '$newDslElement'.\n" +
                        "It will be removed ${deprecationTarget.removalTime}.",
                "$oldDslElement::$newDslElement::${deprecationTarget.name}")
    }

    override fun reportDeprecatedUsage(
            newDslElement: String,
            oldDslElement: String,
            url: String,
            deprecationTarget: DeprecationTarget) {
        issueReporter.reportIssue(
                Type.DEPRECATED_DSL,
                Severity.WARNING,
                "DSL element '$oldDslElement' is obsolete and has been replaced with '$newDslElement'.\n" +
                        "It will be removed ${deprecationTarget.removalTime}.\n" +
                        "For more information, see $url.",
                "$oldDslElement::$newDslElement::${deprecationTarget.name}")
    }

    override fun reportDeprecatedApi(
        newApiElement: String,
        oldApiElement: String,
        url: String,
        deprecationTarget: DeprecationTarget
    ) {
        if (!checkAndSet(oldApiElement)) {
            val debugApi = projectOptions.get(BooleanOption.DEBUG_OBSOLETE_API)

            val messageStart = "API '$oldApiElement' is obsolete and has been replaced with '$newApiElement'.\n" +
                    "It will be removed ${deprecationTarget.removalTime}.\n" +
                    "For more information, see $url."
            var messageEnd = ""

            if (debugApi) {
                val traces = Thread.currentThread().stackTrace

                // special check for the Kotlin plugin.
                val kotlin = traces.filter {
                    it.className.startsWith("org.jetbrains.kotlin.gradle.plugin.")
                }

                messageEnd = if (kotlin.isNotEmpty()) {
                    "REASON: The Kotlin plugin is currently calling this deprecated API." +
                            " Watch https://youtrack.jetbrains.com/issue/KT-25428 and, if possible," +
                            " use a newer version of the Kotlin plugin that has fixed this issue."
                } else {
                    // other cases.
                    // look to see if we get a fileName that's a full path and is a known gradle file.
                    val gradleFile = traces.asSequence().filter {
                        it?.fileName?.let { fileName ->
                            val file = File(fileName)
                            file.isAbsolute && file.isFile && (fileName.endsWith(".gradle") || fileName.endsWith(
                                ".gradle.kts"
                            ))
                        } ?: false
                    }.map {
                        "${it.fileName}:${it.lineNumber}"
                    }.firstOrNull()

                    if (gradleFile != null) {
                        "REASON: Called from: $gradleFile"

                    } else {
                        val formattedTraces = traces.map { "${it.className}.${it.methodName}(${it.fileName}:${it.lineNumber})\n" }

                        "REASON: It is currently called from the following trace:\n" + formattedTraces.joinToString(
                            separator = "",
                            prefix = "",
                            postfix = ""
                        )
                    }

                } + "\nWARNING: Debugging obsolete API calls can take time during configuration. It's recommended to not keep it on at all times."
            } else {
                messageEnd = "To determine what is calling $oldApiElement, use -P${BooleanOption.DEBUG_OBSOLETE_API.propertyName}=true on the command line to display more information."
            }

            issueReporter.reportIssue(
                Type.DEPRECATED_DSL,
                Severity.WARNING,
                "$messageStart\n$messageEnd"
            )

        }
    }

    override fun reportObsoleteUsage(oldDslElement: String,
            deprecationTarget: DeprecationTarget) {
        issueReporter.reportIssue(
                Type.DEPRECATED_DSL,
                Severity.WARNING,
                "DSL element '$oldDslElement' is obsolete and will be removed ${deprecationTarget.removalTime}.",
                "$oldDslElement::::${deprecationTarget.name}")
    }

    override fun reportObsoleteUsage(
            oldDslElement: String,
            url: String,
            deprecationTarget: DeprecationTarget) {
        issueReporter.reportIssue(
                Type.DEPRECATED_DSL,
                Severity.WARNING,
                "DSL element '$oldDslElement' is obsolete and will be removed ${deprecationTarget.removalTime}.\n" +
                        "For more information, see $url.",
                "$oldDslElement::::${deprecationTarget.name}")
    }

    override fun reportRenamedConfiguration(
            newConfiguration: String,
            oldConfiguration: String,
            deprecationTarget: DeprecationTarget,
            url: String?) {
        val msg =
            "Configuration '$oldConfiguration' is obsolete and has been replaced with '$newConfiguration'.\n" +
                    "It will be removed ${deprecationTarget.removalTime}."

        issueReporter.reportIssue(
                Type.DEPRECATED_CONFIGURATION,
                Severity.WARNING,
                if (url != null) "$msg For more information see: $url" else msg,
                "$oldConfiguration::$newConfiguration::${deprecationTarget.name}")
    }

    override fun reportDeprecatedConfiguration(
        newDslElement: String,
        oldConfiguration: String,
        deprecationTarget: DeprecationTarget
    ) {
        issueReporter.reportIssue(
            Type.DEPRECATED_CONFIGURATION,
            Severity.WARNING,
            "Configuration '$oldConfiguration' is obsolete and has been replaced with DSL element '$newDslElement'.\n" +
                    "It will be removed ${deprecationTarget.removalTime}.",
            "$oldConfiguration::$newDslElement::${deprecationTarget.name}")
    }

    override fun reportDeprecatedValue(dslElement: String,
            oldValue: String,
            newValue: String?,
            url: String?,
            deprecationTarget: DeprecationReporter.DeprecationTarget) {
        issueReporter.reportIssue(Type.DEPRECATED_DSL_VALUE,
                Severity.WARNING,
                "DSL element '$dslElement' has a value '$oldValue' which is obsolete " +
                        if (newValue != null)
                            "and has been replaced with '$newValue'.\n"
                        else
                            "and has not been replaced.\n" +
                        "It will be removed ${deprecationTarget.removalTime}.\n",
                url)
    }

    override fun reportDeprecatedOption(
            option: String,
            value: String?,
            deprecationTarget: DeprecationTarget) {
        if (suppressedOptionWarnings.contains(option)) {
            return
        }
        if (!checkAndSet(option, value)) {
            issueReporter.reportIssue(
                Type.UNSUPPORTED_PROJECT_OPTION_USE,
                Severity.WARNING,
                "The option '$option' is deprecated and should not be used anymore.\n" +
                        (if (value != null) "Use '$option=$value' to remove this warning.\n" else "") +
                        "It will be removed ${deprecationTarget.removalTime}."
            )
        }
    }


    override fun reportExperimentalOption(option: Option<*>, value: String) {
        if (suppressedOptionWarnings.contains(option.propertyName)) {
            return
        }
        if (!checkAndSet(option, value)) {
            issueReporter.reportIssue(
                Type.UNSUPPORTED_PROJECT_OPTION_USE,
                Severity.WARNING,
                "The option setting '${option.propertyName}=$value' is experimental and unsupported.\n" +
                        (if (option.defaultValue != null) "The current default is '${option.defaultValue.toString()}'.\n" else "") +
                        option.additionalInfo,
                option.propertyName
            )
        }
    }

    companion object {
        /**
         * Set of obsolete APIs that have been warned already.
         */
        private val obsoleteApis = mutableSetOf<String>()
        private val options = mutableSetOf<OptionInfo>()

        /**
         * Checks if the given API is part of the set already and adds it if not.
         *
         * @return true if the api is already part of the set.
         */
        fun checkAndSet(api: String): Boolean = synchronized(obsoleteApis) {
            return if (obsoleteApis.contains(api)) {
                true
            } else {
                obsoleteApis.add(api)
                false
            }
        }

        /**
         * Checks if the given Option has already been warned about, and adds it if not.
         *
         * @return true if the Option is already part of the set.
         */
        fun checkAndSet(option: Any, value: String?): Boolean = synchronized(options) {
            val info = OptionInfo(option, value)
            return if (options.contains(info)) {
                true
            } else {
                options.add(info)
                false
            }
        }


        fun clean() {
            synchronized(obsoleteApis) {
                obsoleteApis.clear()
            }
            synchronized(options) {
                options.clear()
            }
        }
    }
}

data class OptionInfo(
    val option: Any,
    val value: String?
)
