// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.nio.charset.StandardCharsets
import java.util.Date
import java.util.concurrent.TimeUnit
import org.gradle.api.Project
import org.gradle.api.tasks.testing.Test
import org.gradle.api.tasks.testing.TestDescriptor
import org.gradle.api.tasks.testing.TestListener
import org.gradle.api.tasks.testing.TestResult

class TestConfigurationHelper {

  companion object {

    fun retrace(project: Project, r8jar: File, mappingFile: File, exception: Throwable): String {
      val out = StringBuilder()
      val header = "RETRACED STACKTRACE: " + System.currentTimeMillis()
      out.append("\n--------------------------------------\n")
      out.append("${header}\n")
      out.append("--------------------------------------\n")
      val retracePath = project.getRoot().resolveAll("tools", "retrace.py")
      val command =
        mutableListOf(
          "python3",
          retracePath.toString(),
          "--quiet",
          "--map",
          mappingFile.toString(),
          "--r8jar",
          r8jar.toString(),
        )
      val process = ProcessBuilder(command).start()
      process.outputStream.use { exception.printStackTrace(PrintStream(it)) }
      process.outputStream.close()
      val processCompleted = process.waitFor(20L, TimeUnit.SECONDS) && process.exitValue() == 0
      out.append(process.inputStream.bufferedReader().use { it.readText() })
      if (!processCompleted) {
        out.append(command.joinToString(" ") + "\n")
        out.append("ERROR DURING RETRACING: " + System.currentTimeMillis() + "\n")
        out.append(process.errorStream.bufferedReader().use { it.readText() })
      }
      if (project.hasProperty("print_obfuscated_stacktraces") || !processCompleted) {
        out.append("\n\n--------------------------------------\n")
        out.append("OBFUSCATED STACKTRACE\n")
        out.append("--------------------------------------\n")
        var baos = ByteArrayOutputStream()
        exception.printStackTrace(PrintStream(baos, true, StandardCharsets.UTF_8))
        out.append(baos.toString())
      }
      return out.toString()
    }

    fun setupTestTask(test: Test, isR8Lib: Boolean, r8Jar: File?, r8LibMappingFile: File?) {
      val project = test.project
      if (project.hasProperty("testfilter")) {
        val testFilter = project.property("testfilter").toString()
        test.filter.setFailOnNoMatchingTests(false)
        test.filter.setIncludePatterns(*(testFilter.split("|").toTypedArray()))
      }
      if (project.hasProperty("kotlin_compiler_dev")) {
        test.systemProperty("com.android.tools.r8.kotlincompilerdev", "1")
      }

      if (project.hasProperty("kotlin_compiler_old")) {
        test.systemProperty("com.android.tools.r8.kotlincompilerold", "1")
      }

      if (project.hasProperty("dex_vm") && project.property("dex_vm") != "default") {
        println("NOTE: Running with non default vm: " + project.property("dex_vm"))
        test.systemProperty("dex_vm", project.property("dex_vm")!!)
      }

      // Forward runtime configurations for test parameters.
      if (project.hasProperty("runtimes")) {
        println("NOTE: Running with runtimes: " + project.property("runtimes"))
        test.systemProperty("runtimes", project.property("runtimes")!!)
      }

      if (project.hasProperty("art_profile_rewriting_completeness_check")) {
        test.systemProperty(
          "com.android.tools.r8.artprofilerewritingcompletenesscheck",
          project.property("art_profile_rewriting_completeness_check")!!,
        )
      }

      if (project.hasProperty("disable_assertions")) {
        test.enableAssertions = false
      }

      // Forward project properties into system properties.
      listOf(
          "local_development",
          "slow_tests",
          "desugar_jdk_json_dir",
          "desugar_jdk_libs",
          "test_dir",
          "command_cache_dir",
          "command_cache_stats_dir",
        )
        .forEach {
          val propertyName = it
          if (project.hasProperty(propertyName)) {
            project.property(propertyName)?.let { v -> test.systemProperty(propertyName, v) }
          }
        }

      if (project.hasProperty("no_internal")) {
        test.exclude("com/android/tools/r8/internal/**")
      }
      if (project.hasProperty("only_internal")) {
        test.include("com/android/tools/r8/internal/**")
      }
      if (project.hasProperty("no_arttests")) {
        test.exclude("com/android/tools/r8/art/**")
      }

      if (project.hasProperty("test_xmx")) {
        test.maxHeapSize = project.property("test_xmx")!!.toString()
      } else {
        test.maxHeapSize = "4G"
      }

      if (
        isR8Lib ||
          project.hasProperty("one_line_per_test") ||
          project.hasProperty("update_test_timestamp")
      ) {
        test.addTestListener(
          object : TestListener {
            val testTimes = mutableMapOf<TestDescriptor?, Long>()
            val maxPrintTimesCount = 200

            override fun beforeSuite(desc: TestDescriptor?) {}

            override fun afterSuite(desc: TestDescriptor?, result: TestResult?) {
              if (project.hasProperty("print_times")) {
                // desc.parent == null when we are all done
                if (desc?.parent == null) {
                  testTimes
                    .toList()
                    .sortedByDescending { it.second }
                    .take(maxPrintTimesCount)
                    .forEach { println("${it.first} took: ${it.second}") }
                }
              }
            }

            override fun beforeTest(desc: TestDescriptor?) {
              if (project.hasProperty("one_line_per_test")) {
                println("Start executing ${desc}")
              }
              if (project.hasProperty("print_times")) {
                testTimes[desc] = Date().getTime()
              }
            }

            override fun afterTest(desc: TestDescriptor?, result: TestResult?) {
              if (project.hasProperty("one_line_per_test")) {
                println("Done executing ${desc} with result: ${result?.resultType}")
              }
              if (project.hasProperty("print_times")) {
                testTimes[desc] = Date().getTime() - testTimes[desc]!!
              }
              if (project.hasProperty("update_test_timestamp")) {
                File(project.property("update_test_timestamp")!!.toString())
                  .writeText(Date().getTime().toString())
              }
              if (
                isR8Lib &&
                  result?.resultType == TestResult.ResultType.FAILURE &&
                  result.exception != null
              ) {
                println(
                  retrace(project, r8Jar!!, r8LibMappingFile!!, result.exception as Throwable)
                )
              }
            }
          }
        )
      }

      val userDefinedCoresPerFork = System.getenv("R8_GRADLE_CORES_PER_FORK")
      val processors = Runtime.getRuntime().availableProcessors()
      // See https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html.
      if (!userDefinedCoresPerFork.isNullOrEmpty()) {
        test.maxParallelForks = processors.div(userDefinedCoresPerFork.toInt())
      } else {
        // On work machines this seems to give the best test execution time (without freezing).
        test.maxParallelForks = maxOf(processors.div(8), 1)
        // On low cpu count machines (bots) we under subscribe, so increase the count.
        if (processors == 32) {
          test.maxParallelForks = 15
        }
      }
    }
  }
}
