/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

// Add test duration summary at the end of the build.

def allTests = []
def allSuites = []

allprojects {
  plugins.withType(JavaPlugin) {
    ext {
      testOptions += [
          [propName: 'tests.slowestTests', value: true, description: "Print the summary of the slowest tests."],
          [propName: 'tests.slowestSuites', value: true, description: "Print the summary of the slowest suites."]
      ]
    }

    tasks.withType(Test) { task ->
      if (resolvedTestOption("tests.slowestTests").toBoolean()) {
        afterTest { desc, result ->
          def duration = (result.getEndTime() - result.getStartTime())

          allTests << [
              name    : "${desc.className.replaceAll('.+\\.', "")}.${desc.name} (${project.path})",
              duration: duration
          ]
        }
      }

      if (resolvedTestOption("tests.slowestSuites").toBoolean()) {
        afterSuite { desc, result ->
          // Gradle reports runner times as well, omit anything that isn't attached to a concrete class.
          if (desc.className != null) {
            def duration = (result.getEndTime() - result.getStartTime())

            allSuites << [
                name    : "${desc.className.replaceAll('.+\\.', "")} (${project.path})",
                duration: duration
            ]
          }
        }
      }
    }
  }
}

gradle.buildFinished { result ->
  if (result.getFailure() == null) {
    if (allTests) {
      def slowest = allTests
          .sort { a, b -> b.duration.compareTo(a.duration) }
          .take(10)
          .findAll { e -> e.duration >= 500 }
          .collect { e -> String.format(Locale.ROOT, "%5.2fs %s", e.duration / 1000d, e.name) }

      if (slowest) {
        logger.lifecycle("The slowest tests (exceeding 500 ms) during this run:\n  " +
            slowest.join("\n  "))
      }
    }

    if (allSuites) {
      def slowest = allSuites
          .sort { a, b -> b.duration.compareTo(a.duration) }
          .take(10)
          .findAll { e -> e.duration >= 1000 }
          .collect { e -> String.format(Locale.ROOT, "%5.2fs %s", e.duration / 1000d, e.name) }

      if (slowest) {
        logger.lifecycle("The slowest suites (exceeding 1s) during this run:\n  " +
            slowest.join("\n  "))
      }
    }
  }
}
