plugins {
    id 'java'
    id 'eclipse'
    id 'application'
    id 'pmd'
    id 'jacoco'
    id 'info.solidsoft.pitest' version '1.19.0'
    id 'me.champeau.jmh' version '0.7.2'
    id 'com.palantir.git-version' version '4.0.0'
}

group = 'org.egothor.stemmer'
version = gitVersion(prefix:'release@')

def benchmarkReportsDirectory = layout.buildDirectory.dir('reports/jmh')

configurations {
    mockitoAgent
}

jacoco {
    toolVersion = '0.8.14'
}

pmd {
    consoleOutput = true
    toolVersion = '7.20.0'
    sourceSets = [sourceSets.main]
    ruleSetFiles = files(rootProject.file(".ruleset"))
}

tasks.withType(JavaCompile).configureEach {
    options.release = 21
}

repositories {
    mavenCentral()
}

dependencies {
	jmhImplementation sourceSets.main.output

    testImplementation platform(libs.junit.bom)
    testImplementation libs.junit.jupiter
    testRuntimeOnly libs.junit.platform.launcher

    testImplementation libs.mockito.core
    testImplementation libs.mockito.junit.jupiter
    
    mockitoAgent(libs.mockito.core) {
        transitive = false
    }
}

tasks.withType(Test).configureEach {
    useJUnitPlatform()
    jvmArgs += "-javaagent:${configurations.mockitoAgent.singleFile}"
    
    finalizedBy(tasks.named('jacocoTestReport'))
    
    reports {
        junitXml.required = true
        html.required = true
    }
}

tasks.withType(Pmd).configureEach {
    reports {
        xml.required = true
        html.required = true
    }
}

tasks.named('jacocoTestReport', JacocoReport) {
    dependsOn(tasks.named('test'))

    reports {
        xml.required = true
        csv.required = false
        html.required = true
    }
}

tasks.named('check') {
    dependsOn(tasks.named('jacocoTestReport'))
}

pitest {
    pitestVersion = '1.22.1'
    junit5PluginVersion = '1.2.3'

    targetClasses = [
        'org.egothor.stemmer.*',
        'org.egothor.stemmer.trie.*'
    ]
    targetTests = [
        'org.egothor.stemmer.*Test',
        'org.egothor.stemmer.trie.*Test'
    ]

    excludedClasses = ['org.egothor.stemmer.Compile']
    outputFormats = ['XML', 'HTML']
    timestampedReports = false
    exportLineCoverage = true
    failWhenNoMutations = true
    threads = Math.max(1, Runtime.runtime.availableProcessors().intdiv(2))
}

application {
    mainClass = 'org.egothor.stemmer.Compile'
}

jmh {
    jmhVersion = '1.37'
    warmupIterations = 3
    iterations = 5
    fork = 1
    benchmarkMode = ['avgt']
    timeUnit = 'ns'
    resultFormat = 'CSV'
    resultsFile = benchmarkReportsDirectory.map { it.file('jmh-results.csv').asFile }.get()
    humanOutputFile = benchmarkReportsDirectory.map { it.file('jmh-results.txt').asFile }.get()
    duplicateClassesStrategy = DuplicatesStrategy.EXCLUDE
}

tasks.named('jmh') {
    group = 'verification'
    description = 'Runs JMH benchmarks for the Radixor algorithmic core and Snowball comparison suite.'
}

tasks.register('regressionArtifactGenerator', JavaExec) {
    group = 'verification'
    description = 'Generates deterministic compiled trie regression artifacts.'

    classpath = sourceSets.test.runtimeClasspath
    mainClass = 'org.egothor.stemmer.RegressionArtifactGenerator'

    if (project.hasProperty('regressionInput')) {
        args '--input', project.property('regressionInput').toString()
    }
    if (project.hasProperty('regressionOutput')) {
        args '--output', project.property('regressionOutput').toString()
    }
    if (project.hasProperty('regressionStoreOriginal')) {
        args '--store-original', project.property('regressionStoreOriginal').toString()
    }
    if (project.hasProperty('regressionReductionMode')) {
        args '--reduction-mode', project.property('regressionReductionMode').toString()
    }
}

javadoc {
    failOnError = false

    options.addStringOption('Xdoclint:all,-missing', '-quiet')
    options.addBooleanOption('html5', true)
    options.tags('apiNote:a:API Note:')
    options.tags('implSpec:a:Implementation Requirements:')
    options.tags('implNote:a:Implementation Note:')
    options.tags('param')
    options.tags('return')
    options.tags('throws')
    options.tags('since')
    options.tags('version')
    options.tags('serialData')
    options.tags('factory')
    options.tags('see')

    options.use = true
    options.author = true
    options.version = true
    options.windowTitle = 'Radixor - Egothor Stemmer'
    options.docTitle = 'Radixor - Egothor Stemmer API'

    source = sourceSets.main.allJava
}

apply from: 'gradle/snowball-benchmarks.gradle'

gradle.taskGraph.whenReady { taskGraph ->
    def banner = """
\u001B[34m

8888888888 .d8888b.   .d88888b. 88888888888 888    888  .d88888b.  8888888b.
888       d88P  Y88b d88P" "Y88b    888     888    888 d88P" "Y88b 888   Y88b
888       888    888 888     888    888     888    888 888     888 888    888
8888888   888        888     888    888     8888888888 888     888 888   d88P
888       888  88888 888     888    888     888    888 888     888 8888888P"
888       888    888 888     888    888     888    888 888     888 888 T88b
888       Y88b  d88P Y88b. .d88P    888     888    888 Y88b. .d88P 888  T88b
8888888888 "Y8888P88  "Y88888P"     888     888    888  "Y88888P"  888   T88b

\u001B[36m
 Project : ${project.name}
 Version : ${project.version}
\u001B[0m
"""
    println banner
}
