/*
 *  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.5.0"
}

configurations {
    stats
    testImplementation.extendsFrom(stats)
}

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

jmh {
    jmhVersion = '1.21'
    if (project.hasProperty('benchInclude')) {
        include = ['.*' + project.benchInclude + '.*']
    }
    includeTests = true
    duplicateClassesStrategy = 'WARN'
}
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: compileTestGroovy) {
        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)
}

compileJmhGroovy {
    classpath += compileJmhJava.classpath
}
