/*
 * Copyright 2019 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 androidx.build.uptodatedness

import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.execution.TaskExecutionGraph
import org.gradle.kotlin.dsl.extra
import java.io.File
import java.util.Date

/**
 * Validates that all tasks (except a temporary exception list) are considered up-to-date.
 * The expected usage of this is that the user will invoke a build with the
 * TaskUpToDateValidator disabled, and then reinvoke the same build with the TaskUpToDateValidator
 * enabled. If the second build actually runs any tasks, then some tasks don't have the correct
 * inputs/outputs declared and are running more often than necessary.
 */

const val DISALLOW_TASK_EXECUTION_FLAG_NAME = "disallowExecution"
const val RECORD_FLAG_NAME = "verifyUpToDate"

// Temporary set of exempt tasks that are known to still be out-of-date after running once
// Entries in this set may be task names (like assembleDebug) or task paths
// (like :core:core:assembleDebug)
// Entries in this set do still get rerun because they might produce files that are needed by
// subsequent tasks
val ALLOW_RERUNNING_TASKS = setOf(
    "analyticsRecordingRelease",
    "buildOnServer",
    "checkExternalLicenses",
    "createArchive",
    "createDiffArchiveForAll",
    "createProjectZip",
    "externalNativeBuildDebug",
    "externalNativeBuildRelease",
    "generateJsonModelDebug",
    "generateJsonModelRelease",
    "generateMetadataFileForAndroidDebugPublication",
    "generateMetadataFileForAndroidReleasePublication",
    "generateMetadataFileForDesktopPublication",
    "generateMetadataFileForJvmPublication",
    "generateMetadataFileForJvmlinux-x64Publication",
    "generateMetadataFileForJvmmacos-x64Publication",
    "generateMetadataFileForJvmmacos-arm64Publication",
    "generateMetadataFileForJvmwindows-x64Publication",
    "generateMetadataFileForJvmallPublication",
    "generateMetadataFileForMavenPublication",
    "generateMetadataFileForMetadataPublication",
    "generateMetadataFileForKotlinMultiplatformPublication",
    "generateMetadataFileForPluginMavenPublication",
    "generatePomFileForBenchmarkPluginMarkerMavenPublication",
    "generatePomFileForAndroidDebugPublication",
    "generatePomFileForAndroidReleasePublication",
    "generatePomFileForDesktopPublication",
    "generatePomFileForJvmlinux-x64Publication",
    "generatePomFileForJvmmacos-x64Publication",
    "generatePomFileForJvmmacos-arm64Publication",
    "generatePomFileForJvmwindows-x64Publication",
    "generatePomFileForJvmallPublication",
    "generatePomFileForJvmPublication",
    "generatePomFileForKotlinMultiplatformPublication",
    "generatePomFileForMavenPublication",
    "generatePomFileForPluginMavenPublication",
    "generatePomFileForMetadataPublication",
    "generatePomFileForSafeargsJavaPluginMarkerMavenPublication",
    "generatePomFileForSafeargsKotlinPluginMarkerMavenPublication",
    "jacocoPublicDebug",
    "jacocoTipOfTreeDebug",
    "partiallyDejetifyArchive",
    "publishBenchmarkPluginMarkerMavenPublicationToMavenRepository",
    "publishAndroidDebugPublicationToMavenRepository",
    "publishAndroidReleasePublicationToMavenRepository",
    "publishDesktopPublicationToMavenRepository",
    "publishJvmPublicationToMavenRepository",
    "publishJvmlinux-x64PublicationToMavenRepository",
    "publishJvmmacos-x64PublicationToMavenRepository",
    "publishJvmmacos-arm64PublicationToMavenRepository",
    "publishJvmwindows-x64PublicationToMavenRepository",
    "publishJvmallPublicationToMavenRepository",
    "publishKotlinMultiplatformPublicationToMavenRepository",
    "publishMavenPublicationToMavenRepository",
    "publishMetadataPublicationToMavenRepository",
    "publishPluginMavenPublicationToMavenRepository",
    "publishSafeargsJavaPluginMarkerMavenPublicationToMavenRepository",
    "publishSafeargsKotlinPluginMarkerMavenPublicationToMavenRepository",
    /**
     * relocateShadowJar is used to configure the ShadowJar hence it does not have any outputs.
     * https://github.com/johnrengelman/shadow/issues/561
     */
    "relocateShadowJar",
    "stripArchiveForPartialDejetification",
    "verifyDependencyVersions",
    "zipTestConfigsWithApks",

    ":camera:integration-tests:camera-testapp-core:mergeLibDexDebug",
    ":camera:integration-tests:camera-testapp-core:packageDebug",
    ":camera:integration-tests:camera-testapp-uiwidgets:mergeLibDexDebug",
    ":camera:integration-tests:camera-testapp-uiwidgets:packageDebug",
    ":camera:integration-tests:camera-testapp-core:GenerateTestConfigurationdebug",
    ":camera:integration-tests:camera-testapp-core:GenerateTestConfigurationdebugAndroidTest",
    ":camera:integration-tests:camera-testapp-view:GenerateTestConfigurationdebug",
    ":camera:integration-tests:camera-testapp-view:GenerateTestConfigurationdebugAndroidTest",
    ":camera:integration-tests:camera-testapp-view:mergeLibDexDebug",
    ":camera:integration-tests:camera-testapp-view:packageDebug",
)

// Additional tasks that are expected to be temporarily out-of-date after running once
// Tasks in this set we don't even try to rerun, because they're known to be somewhat slow
// and also known to not generate any new, necessary files during subsequent runs
val DONT_TRY_RERUNNING_TASKS = setOf(
    // More information about the fact that these dokka tasks rerun can be found at b/167569304
    "dokkaKotlinDocs",
    "zipDokkaDocs",

    // We should be able to remove these entries when b/160392650 is fixed
    "lint",
    "lintDebug",
    "lintVitalRelease",
)

class TaskUpToDateValidator {
    companion object {

        private val BUILD_START_TIME_KEY = "taskUpToDateValidatorSetupTime"

        private fun shouldRecord(project: Project): Boolean {
            return project.hasProperty(RECORD_FLAG_NAME)
        }

        private fun shouldValidate(project: Project): Boolean {
            return project.hasProperty(DISALLOW_TASK_EXECUTION_FLAG_NAME)
        }

        private fun isAllowedToRerunTask(task: Task): Boolean {
            return ALLOW_RERUNNING_TASKS.contains(task.name) ||
                ALLOW_RERUNNING_TASKS.contains(task.path)
        }

        private fun shouldTryRerunningTask(task: Task): Boolean {
            return !(
                DONT_TRY_RERUNNING_TASKS.contains(task.name) ||
                    DONT_TRY_RERUNNING_TASKS.contains(task.path)
                )
        }

        private fun recordBuildStartTime(rootProject: Project) {
            rootProject.extra.set(BUILD_START_TIME_KEY, Date())
        }

        private fun getBuildStartTime(project: Project): Date {
            return project.rootProject.extra.get(BUILD_START_TIME_KEY) as Date
        }

        fun setup(rootProject: Project) {
            recordBuildStartTime(rootProject)
            val taskGraph = rootProject.gradle.taskGraph
            if (shouldValidate(rootProject)) {
                taskGraph.beforeTask { task ->
                    if (!shouldTryRerunningTask(task)) {
                        task.enabled = false
                    }
                }
            }
            if (shouldRecord(rootProject) || shouldValidate(rootProject)) {
                taskGraph.afterTask { task ->
                    // In the second build, make sure that the task didn't rerun
                    if (shouldValidate(rootProject)) {
                        if (task.didWork) {
                            if (!isAllowedToRerunTask(task)) {
                                val message = "Ran two consecutive builds of the same tasks," +
                                    " and in the second build, observed $task to be not " +
                                    " UP-TO-DATE. This indicates that $task does not declare" +
                                    " inputs and/or outputs correctly.\n" +
                                    tryToExplainTaskExecution(task, taskGraph)
                                throw GradleException(message)
                            }
                        }
                    }
                    // In the first build, record the task's inputs so that if they change in
                    // the second build then we can compare.
                    // In the second build, also record the task's inputs because we recorded
                    // them in the first build, and we want the two builds to be as similar as
                    // possible
                    if (shouldTryRerunningTask(task) && !isAllowedToRerunTask(task)) {
                        recordTaskInputs(task)
                    }
                }
            }
        }

        fun recordTaskInputs(task: Task) {
            val text = task.inputs.files.files.joinToString("\n")
            val destFile = getTaskInputListPath(task)
            destFile.parentFile.mkdirs()
            destFile.writeText(text)
        }

        fun getTaskInputListPath(task: Task): File {
            return File(getTasksInputListPath(task.project), task.name)
        }

        fun getTasksInputListPath(project: Project): File {
            return File(project.buildDir, "TaskUpToDateValidator/inputs")
        }

        fun checkForChangingSetOfInputs(task: Task): String {
            val previousInputsFile = getTaskInputListPath(task)
            val previousInputs = previousInputsFile.readLines()
            val currentInputs = task.inputs.files.files.map { f -> f.toString() }
            val addedInputs = currentInputs.minus(previousInputs)
            val removedInputs = previousInputs.minus(currentInputs)
            val addedMessage = if (addedInputs.size > 0) {
                "Added these " + addedInputs.size + " inputs: " +
                    addedInputs.joinToString("\n") + "\n"
            } else {
                ""
            }
            val removedMessage = if (removedInputs.size > 0) {
                "Removed these " + removedInputs.size + " inputs: " +
                    removedInputs.joinToString("\n") + "\n"
            } else {
                ""
            }
            return addedMessage + removedMessage
        }

        fun tryToExplainTaskExecution(task: Task, taskGraph: TaskExecutionGraph): String {
            val numOutputFiles = task.outputs.files.files.size
            val outputsMessage = if (numOutputFiles > 0) {
                task.path + " declares " + numOutputFiles + " output files. This seems fine.\n"
            } else {
                task.path + " declares " + numOutputFiles + " output files. This is probably " +
                    "an error.\n"
            }

            val inputFiles = task.inputs.files.files
            var lastModifiedFile: File? = null
            var lastModifiedWhen = Date(0)
            for (inputFile in inputFiles) {
                val modifiedWhen = Date(inputFile.lastModified())
                if (modifiedWhen.compareTo(lastModifiedWhen) > 0) {
                    lastModifiedFile = inputFile
                    lastModifiedWhen = modifiedWhen
                }
            }

            val inputSetModifiedMessage = checkForChangingSetOfInputs(task)
            val inputsMessage = if (inputSetModifiedMessage != "") {
                inputSetModifiedMessage
            } else {
                if (lastModifiedFile != null) {
                    task.path + " declares " + inputFiles.size + " input files. The " +
                        "last modified input file is\n" + lastModifiedFile + "\nmodified at " +
                        lastModifiedWhen + " (this build started at about " +
                        getBuildStartTime(task.project) + "). " +
                        tryToExplainFileModification(lastModifiedFile, taskGraph)
                } else {
                    task.path + " declares " + inputFiles.size + " input files.\n"
                }
            }

            val reproductionMessage = "\nTo reproduce this error you can try running " +
                "`./gradlew ${task.path} -PverifyUpToDate`\n"
            val readLogsMessage = "\nYou can check why Gradle executed ${task.path} by " +
                "passing the '--info' flag to Gradle and then searching stdout for output " +
                "generated immediately before the task began to execute.\n" +
                "Our best guess for the reason that ${task.path} executed is below.\n"
            return readLogsMessage + outputsMessage + inputsMessage + reproductionMessage
        }

        fun getTaskDeclaringFile(file: File, taskGraph: TaskExecutionGraph): Task? {
            for (task in taskGraph.allTasks) {
                if (task.outputs.files.files.contains(file)) {
                    return task
                }
            }
            return null
        }

        fun tryToExplainFileModification(file: File, taskGraph: TaskExecutionGraph): String {
            // Find the task declaring this file as an output,
            // or the task declaring one of its parent dirs as an output
            var createdByTask: Task? = null
            var declaredFile: File? = file
            while (createdByTask == null && declaredFile != null) {
                createdByTask = getTaskDeclaringFile(declaredFile, taskGraph)
                declaredFile = declaredFile.parentFile
            }
            if (createdByTask == null) {
                return "This file is not declared as the output of any task in this build."
            }
            if (isAllowedToRerunTask(createdByTask)) {
                return "This file is declared as an output of " + createdByTask +
                    ", which is a task that is not yet validated by the TaskUpToDateValidator"
            } else {
                return "This file is decared as an output of " + createdByTask +
                    ", which is a task that is validated by the TaskUpToDateValidator " +
                    "(and therefore must not have been out-of-date during this build)"
            }
        }
    }
}
