apply plugin: 'jacoco'

void deleteDirsByPrefix(String dirName, String subDirPrefix) {
    File dir = file(dirName)
    if (dir.exists()) {
        files(dir.listFiles()).each { file ->
            if (file.isDirectory()) {
                if (file.name.startsWith(subDirPrefix)) {
                    println "删除目录 " + file.getAbsolutePath()
                    file.deleteDir()
                }
            }
        }
    }
}

// 将测试代码生成jar包
tasks.register('test_gen_jar', Jar) {
    archiveFileName.set('test.jar')
    destinationDirectory = file("${buildDir}")
    from(sourceSets.test.output) {
        include 'test/callgraph/**'
        // test/java/test/callgraph/field/multi 目录中的类字段太多，解析时可能OOM，排除
        exclude 'test/callgraph/otherjar/**','test/callgraph/field/multi/**'
        into '/'
    }
    from('src/test/resources/') {
        include 'applicationContext.xml'
        into 'resources/'
    }
    from('src/test/resources/') {
        include 'mybatis/**', 'xml_example/**'
        into 'resources/'
    }
    doLast {
        copy {
            from "${buildDir}/test.jar"
            into "${buildDir}/test_jar_1/"
        }
        copy {
            from "${buildDir}/test.jar"
            into "${buildDir}/test_jar_2/"
        }
    }
}

jacocoTestReport {
    reports {
        xml.required.set(false)
        csv.required.set(false)
        html.required.set(true)
        html.outputLocation.set(file("${buildDir}/jacocoReport"))
    }
}

// 拷贝示例对应的java代码
tasks.register('test_copy_example') {
    doFirst {
        def exampleFlag = project.properties.get("example_flag")
        if (exampleFlag != null) {
            println 'example_flag: ' + exampleFlag
            delete 'src/test/java/test/diffjar'
            def srcJavaExampleDir = 'src/test/resources/java_example/example_' + exampleFlag + '/diffjar'
            def javaExampleDirs = new File("${srcJavaExampleDir}").listFiles().findAll { File f -> (f.isDirectory()) }
            javaExampleDirs.each { javaExampleDir ->
                def dirName = javaExampleDir.getName()
                println 'dir_name: ' + dirName
                copy {
                    from "${srcJavaExampleDir}/" + dirName
                    into 'src/test/java/test/diffjar/' + dirName
                }
            }
            delete 'src/src/test/resources/jardiff_mybatis'
            def srcSqlExampleDir = 'src/test/resources/jardiff_mybatis_example/example_' + exampleFlag
            def sqlExampleDirs = new File("${srcSqlExampleDir}").listFiles().findAll { File f -> (f.isDirectory()) }
            sqlExampleDirs.each { javaExampleDir ->
                def dirName = javaExampleDir.getName()
                println 'dir_name: ' + dirName
                copy {
                    from "${srcSqlExampleDir}/" + dirName
                    into 'src/test/resources/jardiff_mybatis/' + dirName
                }
            }
        }
    }
}

compileTestJava.dependsOn(test_copy_example)

// 将用于比较的测试代码生成jar包
tasks.register('test_gen_diff_jar', Jar) {
    def exampleFlag = project.properties.get("example_flag")
    def jarName = 'jar-diff-version-' + exampleFlag + '/jar-diff-' + exampleFlag + '.0.0.jar'
    archiveFileName.set("${jarName}")
    destinationDirectory = file("${buildDir}")
    doFirst {
        println 'example_flag: ' + exampleFlag + ' jarName: ' + jarName
        delete "${buildDir}/" + jarName
    }
    from(sourceSets.test.output) {
        include 'test/diffjar/**', 'xml_example/**', 'jardiff_mybatis/**'
        into '/'
    }
}

// 将用于比较的测试代码生成jar包，包含一个相同的jar包
tasks.register('test_gen_diff_jar_with_same', Jar) {
    def exampleFlag = project.properties.get("example_flag")
    def jarName = 'jar-diff-with-same-' + exampleFlag + '/jar-diff-' + exampleFlag + '.0.0.jar'
    archiveFileName.set("${jarName}")
    destinationDirectory = file("${buildDir}")
    doFirst {
        println 'example_flag: ' + exampleFlag + ' jarName: ' + jarName
        delete "${buildDir}/" + jarName
    }
    if (exampleFlag != null) {
        from(sourceSets.test.output) {
            include 'test/diffjar/**', 'xml_example/**', 'jardiff_mybatis/**'
            into '/'
        }
        copy {
            from "${buildDir}/test.jar"
            into "${buildDir}/jar-diff-with-same-" + exampleFlag + "/"
        }
    }
}

// 将jar-diff-version-目录的文件生成tar.gz包
tasks.register('test_gen_diff_tar_gz', Tar) {
    dependsOn test_gen_diff_jar
    compression = Compression.GZIP
    destinationDirectory = layout.buildDirectory.dir("${buildDir}")
    def exampleFlag = project.properties.get("example_flag")
    // 若使用archiveBaseName，则生成的文件包中会包含“-当前版本号
    archiveFileName.set("jar-diff-version-" + exampleFlag + ".tar.gz")
    destinationDirectory.set(file("${buildDir}/test_diff_tar_gz"))
    from("${buildDir}/jar-diff-version-" + exampleFlag)
}

/*
    生成包含jar文件的jar文件
    需要先执行 gradlew gen_run_jar 命令
 */
tasks.register('gen_jar_in_jar', Jar) {
    archiveFileName = 'jar_output_dir.jar'
    destinationDirectory = file("${buildDir}")

    from(sourceSets.test.output) {
        include 'test/**'
        exclude 'test/callgraph/field/multi/**'
        into '/'
    }

    from(fileTree('jar_output_dir/jar')) {
        into 'jar'
    }

    from(fileTree('jar_output_dir/lib')) {
        into 'lib'
    }
}

/*
    生成包含jar文件的war文件
    需要先执行 gradlew gen_run_jar 命令
 */
tasks.register('gen_jar_in_war', Jar) {
    archiveFileName = 'jar_output_dir.war'
    destinationDirectory = file("${buildDir}")

    from(sourceSets.test.output) {
        include 'test/**'
        exclude 'test/callgraph/field/multi/**'
        into 'WEB-INF/classes'
    }

    from(fileTree('jar_output_dir/lib')) {
        into 'WEB-INF/lib'
    }
}

test {
    dependsOn jar
    doFirst {
        println "需要通过 test_run.bat 执行"
        deleteDirsByPrefix("_jacg_o_ee", "test.runbycode.")
        deleteDirsByPrefix("_jacg_o_er", "test.runbycode.")
        delete "_unittest_output"
        exclude('test/other', 'test/runbycode/targz', 'test/runlocal', 'test/runbycode/TestRBC*')
        minHeapSize = "256m"
        maxHeapSize = "2g"

        maxParallelForks = 1

        forkEvery = 5

        def TEST_FLAG_RECORD_LOG_TO_FILE = "test.flag.record.log.to.file"
        def testFlagRecordLogToFile = System.getProperty(TEST_FLAG_RECORD_LOG_TO_FILE)
        jvmArgs "-Dfile.encoding=UTF-8", "-XX:MetaspaceSize=64m", "-XX:MaxMetaspaceSize=256m",
                "-XX:+HeapDumpOnOutOfMemoryError","-XX:HeapDumpPath=${buildDir}/heap_dump/",
                "-D" + TEST_FLAG_RECORD_LOG_TO_FILE + "=" + testFlagRecordLogToFile

        testLogging {
            events "PASSED", "STARTED", "FAILED", "SKIPPED"
        }
    }
}

/*
    测试代码生成jar包
    gradlew test_gen_jar

    生成用于比较的示例jar包
    gradlew test_gen_diff_jar -Pexample_flag=1
    gradlew test_gen_diff_jar -Pexample_flag=2

    生成用于比较的示例jar包的tar.gz包
    gradlew test_gen_diff_tar_gz -Pexample_flag=1
    gradlew test_gen_diff_tar_gz -Pexample_flag=2

    生成用于比较的示例jar包的tar.gz包，包含一个相同的jar包
    gradlew test_gen_diff_jar_with_same -Pexample_flag=1
    gradlew test_gen_diff_jar_with_same -Pexample_flag=2

    生成包含jar文件的jar文件
    gradlew gen_run_jar
    gradlew gen_jar_in_jar

    生成包含jar文件的war文件
    gradlew gen_run_jar
    gradlew gen_jar_in_war

    使用Gradle执行单元测试时，假如需要将日志中的输出记录到文件，使用以下命令：
    gradlew test -Dtest.flag.record.log.to.file=1

    执行单元测试及代码覆盖率统计
    gradlew test jacocoTestReport
 */
