import dev.vankka.dependencydownload.task.GenerateDependencyDownloadResourceTask
import org.apache.tools.ant.filters.ReplaceTokens

plugins {
    id "dev.vankka.dependencydownload.plugin" version "$dependencyDownloadVersion"
    id "com.github.node-gradle.node" version "3.5.1"
    id "io.swagger.core.v3.swagger-gradle-plugin" version "2.2.7"
}

configurations {
    // Runtime downloading scopes
    mysqlDriver
    sqliteDriver
    testImplementation.extendsFrom mysqlDriver, sqliteDriver
    compileOnly.extendsFrom mysqlDriver, sqliteDriver

    swaggerJson // swagger.json configuration
}

task generateResourceForMySQLDriver(type: GenerateDependencyDownloadResourceTask) {
    var conf = configurations.mysqlDriver
    configuration = conf
    file = "assets/plan/dependencies/" + conf.name + ".txt"
    // Not necessary to include in the resource
    includeShadowJarRelocations = false
}

task generateResourceForSQLiteDriver(type: GenerateDependencyDownloadResourceTask) {
    var conf = configurations.sqliteDriver
    configuration = conf
    file = "assets/plan/dependencies/" + conf.name + ".txt"
    // Not necessary to include in the resource
    includeShadowJarRelocations = false
}

dependencies {
    implementation project(":api")
    shadow project(":extensions")

    shadow "net.playeranalytics:platform-abstraction-layer-api:$palVersion"
    compileOnly "net.kyori:adventure-api:4.12.0"
    shadow("dev.vankka:dependencydownload-runtime:$dependencyDownloadVersion") {
        // Effectively disables relocating
        exclude module: "jar-relocator"
    }
    mysqlDriver "mysql:mysql-connector-java:$mysqlVersion"
    sqliteDriver "org.xerial:sqlite-jdbc:$sqliteVersion"

    shadow "org.apache.commons:commons-text:$commonsTextVersion"
    shadow "org.apache.commons:commons-compress:$commonsCompressVersion"
    shadow "commons-codec:commons-codec:$commonsCodecVersion"
    shadow "com.github.ben-manes.caffeine:caffeine:$caffeineVersion"
    shadow "com.zaxxer:HikariCP:$hikariVersion"
    shadow "org.slf4j:slf4j-nop:$slf4jVersion"
    shadow "org.slf4j:slf4j-api:$slf4jVersion"
    shadow "com.maxmind.geoip2:geoip2:$geoIpVersion"
    shadow "com.google.code.gson:gson:$gsonVersion"
    shadow "org.eclipse.jetty:jetty-server:$jettyVersion"
    shadow "org.eclipse.jetty:jetty-alpn-java-server:$jettyVersion"
    shadow "org.eclipse.jetty.http2:http2-server:$jettyVersion"
    shadow("com.googlecode.json-simple:json-simple:1.1.1") { // json simple used by UUIDFetcher
        // json-simple has junit (a test dependency) compile scoped
        exclude group: "junit", module: "junit"
    }

    // Swagger annotations
    implementation "jakarta.ws.rs:jakarta.ws.rs-api:3.1.0"
    implementation "io.swagger.core.v3:swagger-core-jakarta:$swaggerVersion"
    implementation "io.swagger.core.v3:swagger-jaxrs2-jakarta:$swaggerVersion"

    testImplementation project(":api")
    testArtifacts project(":extensions:adventure")
    testImplementation project(":extensions:adventure")
    testImplementation "com.google.code.gson:gson:$gsonVersion"
    testImplementation "org.seleniumhq.selenium:selenium-java:4.7.2"
    testImplementation "org.testcontainers:testcontainers:$testContainersVersion"
    testImplementation "org.testcontainers:junit-jupiter:$testContainersVersion"
    testImplementation "org.testcontainers:nginx:$testContainersVersion"
}

task updateVersion(type: Copy) {
    from('src/main/resources') {
        include 'plugin.yml'
        include 'bungee.yml'
        include 'nukkit.yml'
        include 'fabric.mod.json'
    }
    into 'build/sources/resources/'
    filter(ReplaceTokens, tokens: [version: '' + project.ext.fullVersion])
}

node {
    download = true
    version = "16.14.2"
    nodeProjectDir = file("$rootDir/react/dashboard")
}

task yarnBundle(type: YarnTask) {
    inputs.files(fileTree("$rootDir/react/dashboard/src"))
    inputs.file("$rootDir/react/dashboard/package.json")

    outputs.dir("$rootDir/react/dashboard/build")

    dependsOn yarn_install
    args = ['run', 'build']
}

task copyYarnBuildResults {
    inputs.files(fileTree("$rootDir/react/dashboard/build"))
    outputs.dir("$rootDir/common/build/resources/main/assets/plan/web")

    dependsOn yarnBundle
    doLast {
        mkdir "$rootDir/common/build/resources/main/assets/plan/web"
        copy {
            from "$rootDir/react/dashboard/build"
            into "$rootDir/common/build/resources/main/assets/plan/web"
        }
    }
}

task determineAssetModifications {
    dependsOn yarnBundle
    inputs.files(fileTree("$rootDir/react/dashboard/build"))
    inputs.files(fileTree(dir: 'src/main/resources/assets/plan/web'))
    inputs.files(fileTree(dir: 'src/main/resources/assets/plan/locale'))
    outputs.file("build/resources/main/assets/plan/AssetVersion.yml")

    doLast {
        mkdir "build/resources/main/assets/plan"
        def versionFile = file("build/resources/main/assets/plan/AssetVersion.yml")
        versionFile.text = "" // Clear previous build
        ConfigurableFileTree tree = fileTree(dir: 'src/main/resources/assets/plan/web')
        tree.forEach { File f ->
            def gitModified = new ByteArrayOutputStream()
            exec {
                commandLine 'git', 'log', '-1', '--pretty=%ct', f.toString()
                standardOutput = gitModified
            }
            def gitModifiedAsString = gitModified.toString().strip()
            // git returns UNIX time in seconds, but most things in Java use UNIX time in milliseconds
            def modified = gitModifiedAsString.isEmpty() ? System.currentTimeMillis() : Long.parseLong(gitModifiedAsString) * 1000
            def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
            versionFile.text += String.format(
                    "%s: %s\n", relativePath.toString().replace('.', ',').replace('\\', '/'), modified
            )
        }
        tree = fileTree(dir: 'src/main/resources/assets/plan/locale')
        tree.forEach { File f ->
            def gitModified = new ByteArrayOutputStream()
            exec {
                commandLine 'git', 'log', '-1', '--pretty=%ct', f.toString()
                standardOutput = gitModified
            }
            def gitModifiedAsString = gitModified.toString().strip()
            // git returns UNIX time in seconds, but most things in Java use UNIX time in milliseconds
            def modified = gitModifiedAsString.isEmpty() ? System.currentTimeMillis() : Long.parseLong(gitModifiedAsString) * 1000
            def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
            versionFile.text += String.format(
                    "%s: %s\n", relativePath.toString().replace('.', ',').replace('\\', '/'), modified
            )
        }

        tree = fileTree("$rootDir/react/dashboard/build")
        tree.forEach { File f ->
            if (f.getName().endsWith(".map")) return
            def modified = System.currentTimeMillis()
            def relativePath = tree.getDir().toPath().relativize(f.toPath()) // File path relative to the tree
            versionFile.text += String.format(
                    "%s: %s\n", relativePath.toString().replace('.', ',').replace('\\', '/'), modified
            )
        }
    }
}

resolve { // Swagger json generation task
    outputFileName = 'swagger'
    outputFormat = 'JSON'
    prettyPrint = 'TRUE'
    classpath = sourceSets.main.runtimeClasspath
    buildClasspath = classpath
    resourcePackages = [
            'com.djrapitops.plan.delivery.webserver',
            'com.djrapitops.plan.delivery.webserver.resolver.auth',
            'com.djrapitops.plan.delivery.webserver.resolver.json',
    ]
    outputDir = file('build/generated-resources/swagger/assets/plan/web/')
}
task swaggerJsonJar(type: Jar) {
    dependsOn resolve
    archiveClassifier.set("resolve")
    from 'build/generated-resources/swagger'
}
artifacts {
    swaggerJson swaggerJsonJar
}

processResources {
    dependsOn copyYarnBuildResults
    dependsOn determineAssetModifications
    dependsOn generateResourceForMySQLDriver
    dependsOn generateResourceForSQLiteDriver
    dependsOn updateVersion
    duplicatesStrategy = DuplicatesStrategy.INCLUDE
    from 'build/sources/resources'
}

shadowJar {
    configurations = [project.configurations.shadow]
}
