/*
 * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

import org.gradle.api.Task
import org.gradle.api.execution.TaskExecutionListener
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
import org.gradle.api.tasks.TaskState
import java.util.HashMap

if (isConfigurationCacheDisabled) {
    BuildTimeReporter.configure(gradle)
}

private class BuildTimeReporter(
    private val kotlinCompileClass: Class<*>,
    private val javaCompileClass: Class<*>,
    private val jarClass: Class<*>,
    private val proguardClass: Class<*>
) : TaskExecutionListener {
    companion object {
        fun configure(gradle: Gradle) {
            val rootProject = gradle.rootProject
            val logger = rootProject.logger
            val classloader = rootProject.buildscript.classLoader

            fun findClass(name: String): Class<*>? =
                try {
                    Class.forName(name, false, classloader)
                } catch (e: ClassNotFoundException) {
                    logger.warn("Could not find class '$name'. Build times won't be reported")
                    null
                }

            val reporter = BuildTimeReporter(
                kotlinCompileClass = findClass("org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile") ?: return,
                javaCompileClass = findClass("org.gradle.api.tasks.compile.JavaCompile") ?: return,
                jarClass = findClass("org.gradle.jvm.tasks.Jar") ?: return,
                proguardClass = findClass("proguard.gradle.ProGuardTask") ?: return
            )
            gradle.taskGraph.addTaskExecutionListener(reporter)
            gradle.buildFinished {
                reporter.report(logger)
            }
        }
    }

    private enum class TaskCategory {
        COMPILING_KOTLIN,
        COMPILING_JAVA,
        PROCESSING_JARS,
        UNCATEGORIZED;

        private fun String.toTitleCase() =
            if (length <= 1) capitalize() else { get(0).toUpperCase() + substring(1).toLowerCase() }

        fun description(): String =
            name.replace("_", " ").toTitleCase()
    }

    private val taskStartTime = HashMap<Task, Long>()
    private val categoryTimeNs = HashMap<TaskCategory, Long>()
    private var totalTimeNs = 0L

    @Synchronized
    override fun beforeExecute(task: Task) {
        taskStartTime[task] = System.nanoTime()
    }

    @Synchronized
    override fun afterExecute(task: Task, state: TaskState) {
        val startTimeNs = taskStartTime.remove(task) ?: return
        val endTimeNs = System.nanoTime()
        val timeNs = endTimeNs - startTimeNs
        totalTimeNs += timeNs
        val category = taskCategory(task)
        categoryTimeNs[category] = (categoryTimeNs[category] ?: 0L) + timeNs
    }

    private fun taskCategory(task: Task): TaskCategory = when {
        kotlinCompileClass.isInstance(task) -> TaskCategory.COMPILING_KOTLIN
        javaCompileClass.isInstance(task) -> TaskCategory.COMPILING_JAVA
        jarClass.isInstance(task) ||
                proguardClass.isInstance(task) -> TaskCategory.PROCESSING_JARS
        else -> TaskCategory.UNCATEGORIZED
    }

    private fun Double.asShortString() =
        String.format("%.2f", this)

    @Synchronized
    private fun report(log: Logger) {
        val secondInNs = 1000_000_000
        val totalTimeSec = totalTimeNs.toDouble() / secondInNs
        if (totalTimeSec < 1) return

        log.info("Build time for tasks:")
        for (category in TaskCategory.values()) {
            val timeNs = categoryTimeNs[category] ?: 0L
            val timeSec = timeNs.toDouble() / secondInNs
            if (timeSec < 1) continue

            val percent = timeSec / totalTimeSec * 100
            log.info("${category.description()}: ${timeSec.asShortString()}s (${percent.asShortString()}% of total time)")
        }
    }
}
