import java.nio.file.Files

// Aggregate Javadocs
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.netflix.nebula:gradle-aggregate-javadocs-plugin:3.0.+'
    }
}

plugins {
    id "com.github.johnrengelman.shadow" version "8.1.1" apply false
    id "java"
    id 'java-library'
    id "jacoco"
    id "checkstyle"
    id "org.sonarqube" version "4.4.1.3373"
    id 'fabric-loom' version '1.3-SNAPSHOT' apply false
}

apply plugin: 'nebula-aggregate-javadocs'

def determineBuildVersion = {
    def buildInfo = new ByteArrayOutputStream()
    exec {
        commandLine 'git', 'rev-list', '--count', 'HEAD'
        standardOutput = buildInfo
    }
    // Magic number: git rev-list --count cdb13e3b663b18e3938ad5efc60d165fa9301f6e
    return Integer.parseInt(buildInfo.toString().replaceAll("[^0-9]", "")) - 3529
}
def buildVersion = determineBuildVersion()

allprojects {

    group "com.djrapitops"
    version "5.6-SNAPSHOT"

    ext.majorVersion = '5'
    ext.minorVersion = '6'
    ext.buildVersion = buildVersion
    ext.fullVersion = project.ext.majorVersion + '.' + project.ext.minorVersion + ' build ' + project.ext.buildVersion
    ext.fullVersionFilename = project.ext.majorVersion + '.' + project.ext.minorVersion + '-build-' + project.ext.buildVersion
    ext.fullVersionSemantic = project.ext.majorVersion + '.' + project.ext.minorVersion + '+build.' + project.ext.buildVersion

    // Fix for UTF-8 files showing with wrong encoding when compiled on Windows machines.
    compileJava { options.encoding = "UTF-8" }
    tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' }
    javadoc { options.encoding = 'UTF-8' }
}

logger.lifecycle("Building artifact for version $fullVersion / $fullVersionFilename / $fullVersionSemantic")

subprojects {
    // Build plugins
    apply plugin: "com.github.johnrengelman.shadow"
    apply plugin: "java"
    apply plugin: "java-library"
    apply plugin: "maven-publish"

    // Report plugins
    apply plugin: "checkstyle"
    apply plugin: "jacoco"

    compileJava {
        options.release = 11
    }

    ext {
        daggerVersion = "2.51"

        palVersion = "5.1.0"

        bukkitVersion = "1.13.2-R0.1-SNAPSHOT"
        spigotVersion = "1.13.2-R0.1-SNAPSHOT"
        paperVersion = "1.13.2-R0.1-SNAPSHOT"
        spongeVersion = "8.1.0"
        nukkitVersion = "1.0-SNAPSHOT"
        bungeeVersion = "1.16-R0.4"
        velocityVersion = "3.0.0-SNAPSHOT"
        redisBungeeVersion = "0.3.8-SNAPSHOT"
        redisBungeeProxioDevVersion = "0.7.3"

        commonsTextVersion = "1.11.0"
        commonsCompressVersion = "1.26.1"
        commonsCodecVersion = "1.16.1"
        caffeineVersion = "3.1.8"
        jettyVersion = "11.0.20"
        caffeineVersion = "2.9.2"
        mysqlVersion = "8.3.0"
        mariadbVersion = "3.3.3"
        sqliteVersion = "3.42.0.1"
        adventureVersion = "4.14.0"
        hikariVersion = "5.1.0"
        slf4jVersion = "2.0.11"
        geoIpVersion = "4.2.0"
        gsonVersion = "2.10.1"
        dependencyDownloadVersion = "1.3.1"
        ipAddressMatcherVersion = "5.5.0"
        jasyptVersion = "1.9.3"

        bstatsVersion = "3.0.2"
        placeholderapiVersion = "2.11.5"
        nkPlaceholderapiVersion = "1.4-SNAPSHOT"

        junitVersion = "5.10.2"
        mockitoVersion = "5.11.0"
        testContainersVersion = "1.19.7"
        swaggerVersion = "2.2.21"
    }

    repositories {
        mavenCentral()
        google()
        maven { url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" } // Spigot
        maven { url = "https://papermc.io/repo/repository/maven-public/" } // Paper
        maven { url = "https://repo.spongepowered.org/repository/maven-public/" } // Sponge
        maven { url = "https://oss.sonatype.org/content/repositories/snapshots" } // BungeeCord
        maven { url = "https://repo.playeranalytics.net/releases" } // Plan
        maven { url = "https://repo.md-5.net/content/repositories/snapshots/" } // RedisBungee
        maven { url = "https://jitpack.io" } // RedisBungee fork
    }

    dependencies {
        // Dependency Injection used across the project
        shadow "com.google.dagger:dagger:$daggerVersion"
        annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"
        testImplementation "com.google.dagger:dagger:$daggerVersion"
        testAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion"

        compileOnly "io.swagger.core.v3:swagger-core-jakarta:$swaggerVersion"

        // Test Tooling Dependencies
        testImplementation "org.junit.jupiter:junit-jupiter:$junitVersion"      // JUnit 5
        testImplementation "org.mockito:mockito-core:$mockitoVersion"           // Mockito Core
        testImplementation "org.mockito:mockito-junit-jupiter:$mockitoVersion"  // Mockito JUnit 5 Extension
        testImplementation "com.jayway.awaitility:awaitility:1.7.0"
        // Awaitility (Concurrent wait conditions)

        // Testing dependencies required by Plan
        testImplementation "org.xerial:sqlite-jdbc:$sqliteVersion" // SQLite
        testImplementation "com.mysql:mysql-connector-j:$mysqlVersion" // MySQL
        testImplementation "org.mariadb.jdbc:mariadb-java-client:$mariadbVersion" // MariaDB
    }

    configurations {
        // Include shadowed dependencies in compile classpath of dependent modules
        api.extendsFrom shadow

        testArtifacts.extendsFrom testRuntimeOnly // Test classes available to other modules
        testImplementation.extendsFrom shadow // Include shadowed dependencies in test classpath
    }
    // Test classes available to other modules
    tasks.register('testJar', Jar) {
        archiveClassifier.set("test")
        from sourceSets.test.output
    }
    artifacts {
        testArtifacts testJar
    }

    test {
        useJUnitPlatform()
        testLogging {
            events "passed", "failed", "skipped"
            exceptionFormat "full"
        }
    }

    checkstyle {
        toolVersion "8.44"
        getConfigDirectory().set file("$rootProject.projectDir/config/checkstyle")
    }

    jacocoTestReport {
        reports {
            xml.required = true
            // xml.destination file("${buildDir}/jacoco/report.xml")
        }
    }

    plugins.withType(JacocoPlugin).configureEach {
        tasks.named("test").get().finalizedBy 'jacocoTestReport'
    }
}

sonarqube {
    properties {
        property "sonar.projectName", "Player Analytics"
        property "sonar.projectKey", "com.djrapitops:Plan"
        property "sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml"
    }
}

abstract class PrintSnapshotVersionTask extends DefaultTask {
    @TaskAction
    def print() {
        def versionsDir = project.file("$project.buildDir/versions")
        def textFile = project.file("$project.buildDir/versions/snapshot.txt")
        versionsDir.mkdirs()
        Files.deleteIfExists(textFile.toPath())
        textFile.createNewFile()
        textFile << "$project.version"
    }
}

abstract class PrintJarNameVersionTask extends DefaultTask {
    @TaskAction
    def print() {
        def versionsDir = project.file("$project.buildDir/versions")
        def textFile = project.file("$project.buildDir/versions/jar.txt")
        versionsDir.mkdirs()
        Files.deleteIfExists(textFile.toPath())
        textFile.createNewFile()
        textFile << "$project.majorVersion.$project.minorVersion-build-$project.buildVersion"
    }
}

abstract class PrintHumanReadableVersionTask extends DefaultTask {
    @TaskAction
    def print() {
        def versionsDir = project.file("$project.buildDir/versions")
        def textFile = project.file("$project.buildDir/versions/human.txt")
        versionsDir.mkdirs()
        Files.deleteIfExists(textFile.toPath())
        textFile.createNewFile()
        textFile << "$project.fullVersion"
    }
}

// Create a task using the task type
tasks.register('snapshotVersion', PrintSnapshotVersionTask)
tasks.register('jarNameVersion', PrintJarNameVersionTask)
tasks.register('humanReadableVersion', PrintHumanReadableVersionTask)
