/*
 * 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.
 */

package org.jetbrains.kotlin.idea.perf

import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase
import com.intellij.ide.impl.ProjectUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ex.ApplicationEx
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import java.io.File
import java.io.PrintWriter
import java.io.StringWriter

abstract class WholeProjectPerformanceTest : DaemonAnalyzerTestCase(), WholeProjectFileProvider {

    private val rootProjectFile: File = File("../perfTestProject").absoluteFile
    private val statsFile: File = File("build/stats.csv").absoluteFile
    private val tmp = rootProjectFile

    override fun setUpProject() {

        println("Using project in $tmp")

        tmp.resolve(".idea").deleteRecursively()

        (ApplicationManager.getApplication() as ApplicationEx).doNotSave()
        myProject = ProjectUtil.openOrImport(tmp.path, null, false)
    }

    data class PerFileTestResult(val perProcess: Map<String, Long>, val totalNs: Long, val errors: List<Throwable>)

    protected abstract fun doTest(file: VirtualFile): PerFileTestResult

    fun testWholeProjectPerformance() {

        tcSuite(this::class.simpleName ?: "Unknown") {
            val totals = mutableMapOf<String, Long>()

            val statsOutput = statsFile.bufferedWriter()

            statsOutput.appendln("File, ProcessID, Time")

            fun appendInspectionResult(file: String, id: String, nanoTime: Long) {
                totals.merge(id, nanoTime) { a, b -> a + b }

                statsOutput.appendln(buildString {
                    append(file)
                    append(", ")
                    append(id)
                    append(", ")
                    append(nanoTime.nsToMs)
                })
            }

            tcSuite("TotalPerFile") {
                val files = provideFiles(project)

                files.forEach {
                    val filePath = File(it.path).relativeTo(tmp).path.replace(File.separatorChar, '/')
                    tcTest(filePath) {
                        val result = doTest(it)
                        result.perProcess.forEach { (k, v) ->
                            appendInspectionResult(filePath, k, v)
                        }
                        (result.totalNs.nsToMs) to result.errors
                    }
                }
            }

            statsOutput.flush()
            statsOutput.close()


            tcSuite("Total") {
                totals.forEach { (k, v) ->
                    tcTest(k) {
                        v.nsToMs to emptyList()
                    }
                }
            }
        }
    }

    inline fun tcSuite(name: String, block: () -> Unit) {
        println("##teamcity[testSuiteStarted name='$name']")
        block()
        println("##teamcity[testSuiteFinished name='$name']")
    }

    inline fun tcTest(name: String, block: () -> Pair<Long, List<Throwable>>) {
        println("##teamcity[testStarted name='$name' captureStandardOutput='true']")
        val (time, errors) = block()
        if (errors.isNotEmpty()) {
            val detailsWriter = StringWriter()
            val errorDetailsPrintWriter = PrintWriter(detailsWriter)
            errors.forEach {
                it.printStackTrace(errorDetailsPrintWriter)
                errorDetailsPrintWriter.println()
            }
            errorDetailsPrintWriter.close()
            val details = detailsWriter.toString()
            println("##teamcity[testFailed name='$name' message='Exceptions reported' details='${details.tcEscape()}']")
        }
        println("##teamcity[testFinished name='$name' duration='$time']")
    }

    fun String.tcEscape(): String {
        return this
            .replace("|", "||")
            .replace("[", "|[")
            .replace("]", "|]")
            .replace("\r", "|r")
            .replace("\n", "|n")
            .replace("'", "|'")
    }

    protected fun PsiElement.acceptRecursively(visitor: PsiElementVisitor) {
        this.accept(visitor)
        for (child in this.children) {
            child.acceptRecursively(visitor)
        }
    }

    companion object {
        val Long.nsToMs get() = (this * 1e-6).toLong()
    }

}