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

import java.text.DecimalFormat

plugins {
    id "me.champeau.gradle.jmh" version "0.4.8"
}

configurations {
    stats
    testImplementation.extendsFrom(stats)
}

dependencies {
    jmh rootProject
    testImplementation 'org.codehaus.groovy:groovy-all:2.4.12'
    stats 'org.apache.commons:commons-math3:3.6'
}

jmh {
    jmhVersion = '1.19'
    if (project.hasProperty('benchInclude')) {
        include = ['.*' + project.benchInclude + '.*']
    }
    includeTests = true
}
jmhClasses.dependsOn clean

sourceCompatibility = 1.8
targetCompatibility = 1.8

task performanceTests {
    ext.outputDir = file("$buildDir/compilation")
    ext.dataFile = file("$buildDir/compilation-stats.csv")

    dependsOn rootProject.jar
    doLast {
        ext.outputDir.deleteDir()
        def versions = []
        dataFile.eachLine {
            def (version, mean, stdDev) = it.split(';')
            mean = Double.valueOf(mean)
            stdDev = Double.valueOf(stdDev)
            versions << [version == project.version ? 'current' : version, mean, stdDev]
        }
        versions = versions.sort { it[1] }
        def fastest = versions[0][1]
        versions.each { version, mean, stdDev ->
            print "Groovy $version Average ${mean}ms ± ${new DecimalFormat("#.##").format(stdDev)}ms "
            if (mean > fastest) {
                def diff = 100 * (mean - fastest) / fastest
                print "(${new DecimalFormat("#.##").format(diff)}% slower)"
            }
            println()
        }
        dataFile.delete()
    }
}

['1.8.9', '2.0.8', '2.1.9', '2.2.2', '2.3.10', '2.3.11', '2.4.7', 'current'].each { version ->
    def t = task "performanceTestGroovy${version.replace('.', '_')}"(type: JavaExec) {
        dependsOn compileTestJava
        def groovyConf = configurations.detachedConfiguration(
                dependencies.create(
                        'current' == version ? files(rootProject.jar.archivePath) : "org.codehaus.groovy:groovy:$version")
        )
        groovyConf.transitive = false
        main = 'org.apache.groovy.perf.CompilerPerformanceTest'
        classpath = groovyConf + sourceSets.test.output + configurations.stats
        jvmArgs = ['-Xms512m', '-Xmx512m', '-XX:MaxPermSize=512m']

        // configure some files to compile. This is an arbitrary set of files which can be compiled
        // independently of the version of Groovy being tested
        def testFiles = ['gls/CompilableTestSupport.groovy',
                         'groovy/beans',
                         'groovy/benchmarks',
                         'groovy/execute',
                         'groovy/gpath',
                         'groovy/io',
                         'groovy/script',
                         'groovy/time',
                         'groovy/tree',
                         'gls/syntax'].collect { "../../src/test/$it" }
        ['groovy-ant', 'groovy-test', 'groovy-jsr223'].collect(testFiles) { "../../subprojects/$it/src/test/groovy" }

        ['ackermann', 'fibo', 'random', 'spectralnorm', 'ary', 'hello', 'recursive', 'threadring',
         'binarytrees', 'mandelbrot', 'regexdna', 'wordfreq',
         'fannkuch', 'nsieve', 'revcomp'].collect(testFiles) {
            "../../benchmark/bench/${it}.groovy"
        }

        doFirst {
            def compileClassPath = [
                    '-cp',
                    groovyConf.files[0]
            ]
            rootProject.sourceSets.test.compileClasspath.files
                    .findAll { it.name.endsWith('jar') && !it.name.contains('groovy') && !it.name.contains('antlr') && !it.name.contains('asm') }
                    .collect(compileClassPath) { it.absolutePath }

            args = [
                    *testFiles,
                    *compileClassPath
            ]
        }

    }
    performanceTests.dependsOn(t)
}
