/*
 * Copyright 2010-2018 JetBrains s.r.o. 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

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.warn("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.warn("${category.description()}: ${timeSec.asShortString()}s (${percent.asShortString()}% of total time)")
        }
    }
}