/*
 * This file is part of Applied Energistics 2.
 * Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
 *
 * Applied Energistics 2 is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Applied Energistics 2 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Applied Energistics 2.  If not, see <http://www.gnu.org/licenses/lgpl>.
 */

plugins {
    id 'net.neoforged.moddev'
    id 'maven-publish'
    id 'signing'
    id 'com.diffplug.spotless'
}

apply plugin: ProjectDefaultsPlugin
apply plugin: CrowdinPlugin

base {
    archivesName = "appliedenergistics2"
}

neoForge.version = project.neoforge_version

sourceSets {
    main {
        resources {
            srcDir 'src/generated/resources'
        }
    }
    buildtools
}

configurations {
    localRuntimeOnly
    buildtoolsImplementation.extendsFrom(compileClasspath)
    // Dependencies only used for the guide export, but not shipped
    guideExportOnly
    configurations.compileClasspath.extendsFrom(guideExportOnly)
    configurations.runtimeClasspath.extendsFrom(guideExportOnly)

    runtimeClasspath.extendsFrom localRuntimeOnly
}

import appengbuild.*
import com.diffplug.gradle.spotless.JsonExtension

dependencies {
    // Used for the guide export
    guideExportOnly("org.bytedeco:ffmpeg-platform:${ffmpeg_version}")

    implementation("org.appliedenergistics:guideme:${guideme_version}")

    // compile against provided APIs
    compileOnly "dev.emi:emi-neoforge:${emi_version}:api"
    compileOnly "me.shedaniel:RoughlyEnoughItems-neoforge:${project.rei_version}"
    compileOnly "mcp.mobius.waila:wthit-api:neo-${project.wthit_version}"
    compileOnly "curse.maven:jade-324717:${project.jade_file_id}"
    compileOnly "mcjty.theoneprobe:theoneprobe:${project.top_version}"

    switch (project.runtime_itemlist_mod) {
        case "emi":
            localRuntimeOnly "dev.emi:emi-neoforge:${emi_version}"
            break
        case "rei":
            localRuntimeOnly "me.shedaniel:RoughlyEnoughItems-neoforge:${project.rei_version}"
            break
    }

    switch (project.runtime_tooltip_mod) {
        case "wthit":
            localRuntimeOnly "mcp.mobius.waila:wthit:neo-${project.wthit_version}"
            break
        case "jade":
            localRuntimeOnly "curse.maven:jade-324717:${project.jade_file_id}"
            break
        case "top":
            localRuntimeOnly "mcjty.theoneprobe:theoneprobe:${project.top_version}"
            break
    }

    if (project.runtime_curio == "true") {
        localRuntimeOnly("top.theillusivec4.curios:curios-neoforge:${project.curios_version}")
    }

    // Athena
    if (project.runtime_athena == "true") {
        localRuntimeOnly("curse.maven:athena-841890:${project.athena_file_id}")
    }

    // unit test dependencies
    testImplementation(platform("org.junit:junit-bom:${project.junit_version}"))
    testImplementation(platform("org.assertj:assertj-bom:${project.assertj_version}"))
    testImplementation("org.junit.jupiter:junit-jupiter-api")
    testImplementation("org.junit.jupiter:junit-jupiter-params")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
    testImplementation("org.junit.platform:junit-platform-launcher")
    testImplementation("org.assertj:assertj-core")
    testImplementation("com.google.guava:guava-testlib:21.0")
    testImplementation("org.mockito:mockito-junit-jupiter:5.12.0")
    testImplementation("net.neoforged:testframework:${project.neoforge_version}")
}

test {
    useJUnitPlatform()

    // Might not need this anymore...
    systemProperty "guideme.ae2.guide.sources", file("guidebook").absolutePath
}

dependencies {
    buildtoolsImplementation 'de.siegmar:fastcsv:2.1.0'
    buildtoolsImplementation 'com.google.code.gson:gson:2.8.9'
}

neoForge {
    validateAccessTransformers = true

    mods {
        ae2 {
            sourceSet sourceSets.main
        }
    }

    runs {
        configureEach {
            gameDirectory = project.file('run')
            systemProperty('appeng.tests', 'true')
            // systemProperty('mixin.debug.export', 'true')
            logLevel = org.slf4j.event.Level.INFO
            systemProperty('guideme.ae2.guide.sources', file('guidebook').absolutePath)
        }
        client {
            client()
            systemProperty('appeng.tests', 'true')
        }
        gametestWorld {
            client()
            programArguments = [
                    '--username', 'AE2Dev', '--quickPlaySingleplayer', 'GametestWorld'
            ]
            systemProperty('appeng.tests', 'true')
        }
        guide {
            client()

            systemProperty('guideme.showOnStartup', 'ae2:guide')
        }
        server {
            server()
        }
        data {
            data()
            programArguments = [
                    '--mod', 'ae2',
                    '--all',
                    '--output', file('src/generated/resources/').absolutePath,
                    '--existing', file('src/main/resources').absolutePath
            ]
        }
        guideexport {
            client()
            systemProperty('appeng.runGuideExportAndExit', 'true')
            systemProperty('appeng.guideExportFolder', file('build/guide').absolutePath)
        }
        // Use to run the tests
        gametest {
            type = 'gameTestServer'
            gameDirectory = project.file('build/gametest')
        }
    }

    unitTest {
        enable()
        testedMod = mods.ae2
    }
}

configurations.additionalRuntimeClasspath.extendsFrom configurations.guideExportOnly

//////////////
// Artifacts
final generateModMetadata = tasks.register('generateModMetadata', ProcessResources) {
    group = 'build'
    from('src/main/neoforge.mods.toml') {
        rename '(.*)', 'META-INF/$1'
    }
    into 'build/generated/modMetadata'

    // Exposed project properties
    Map<String, String> projectProperties = [
            'version',
            'minecraft_version',
            'neoforge_version_range',
            'top_version_range',
            'jade_version_range',
            'guideme_version'
    ].collectEntries { [it, project[it]] }

    // Ensure the resources get re-evaluate when the version changes
    inputs.properties projectProperties
    expand projectProperties
}
sourceSets.main.resources.srcDir generateModMetadata
neoForge.ideSyncTask generateModMetadata

tasks.named('jar', Jar) {
    exclude '/.cache'
    from('guidebook') {
        into 'assets/ae2/ae2guide'
    }
}

static void publicApiIncludePatterns(PatternFilterable spec) {
    spec.exclude "**/*Internal.*"
    spec.exclude "**/*Internal\$*.*"
    spec.include "appeng/api/**"
}

tasks.named('javadoc', Javadoc) {
    source = sourceSets.main.allJava
    classpath = sourceSets.main.compileClasspath + sourceSets.main.output

    options.addStringOption('Xdoclint:none', '-quiet')
    options.encoding = 'UTF-8'
    options.charSet = 'UTF-8'
    publicApiIncludePatterns(it)
}

tasks.register('apiJar', Jar) {
    archiveClassifier = "api"
    // api jar ist just a development aid and serves as both a binary and source jar simultaneously
    from sourceSets.main.output
    from sourceSets.main.allJava
    publicApiIncludePatterns(it)
}

artifacts {
    archives javadocJar
    archives sourcesJar
    archives apiJar
}

//////////////////
// Maven publish
publishing {
    publications {
        maven(MavenPublication) {
            artifactId = "appliedenergistics2"
            version = project.version
            pom {
                name = "Applied Energistics 2"
                description = "A Minecraft mod about Matter, Energy and using them to conquer the world..."
                url = "https://appliedenergistics.org"
                scm {
                    connection = "scm:git:git://github.com/AppliedEnergistics/Applied-Energistics-2.git"
                    developerConnection = "scm:git:ssh://github.com:AppliedEnergistics/Applied-Energistics-2.git"
                    url = "https://github.com/AppliedEnergistics/Applied-Energistics-2/tree/main"
                }
                licenses {
                    license {
                        name = "LGPLv3, MIT, CC BY-NC-SA 3.0"
                        url = "https://github.com/AppliedEnergistics/Applied-Energistics-2?tab=readme-ov-file#license"
                    }
                }
                developers {
                    developer {
                        name = "Technici4n"
                        email = "team@appliedenergistics.org"
                        organization = "Applied Energistics"
                        organizationUrl = "https://github.com/AppliedEnergistics/"
                    }
                    developer {
                        name = "shartte"
                        email = "team@appliedenergistics.org"
                        organization = "Applied Energistics"
                        organizationUrl = "https://github.com/AppliedEnergistics/"
                    }
                }
            }

            from(components.java)
            artifact apiJar
        }
    }
    repositories {
        maven {
            name = "Local"
            url = file("build/repo").toURI()
        }
    }
}

/////////////
// Spotless
spotless {

    java {
        target 'src/*/java/appeng/**/*.java'

        endWithNewline()
        indentWithSpaces()
        removeUnusedImports()
        toggleOffOn()
        eclipse().configFile 'codeformat/codeformat.xml'
        importOrderFile 'codeformat/ae2.importorder'

        // courtesy of diffplug/spotless#240
        // https://github.com/diffplug/spotless/issues/240#issuecomment-385206606
        custom 'noWildcardImports', {
            if (it.contains('*;\n')) {
                throw new Error('No wildcard imports allowed')
            }

            it
        }
        bumpThisNumberIfACustomStepChanges(1)
    }

   json {
        target 'src/*/resources/**/*.json'
        targetExclude 'src/generated/resources/**'
        var biomeConfig = it.new JsonExtension.BiomeJson(null)
        try {
            biomeConfig.downloadDir(new File(rootDir, ".gradle/biome").absolutePath)
        } catch (Exception ignored) {
        }
        addStep(biomeConfig.createStep())
        indentWithSpaces(2)
        endWithNewline()
    }
}

////////////////
check.dependsOn tasks.register('validateResources', JavaExec) {
    group = "verification"
    classpath = sourceSets.buildtools.runtimeClasspath
    mainClass = 'ValidateResourceIds'
    workingDir "."
    args "guidebook"
    javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
}

signing {
    String signingKey = findProperty("signingKey")
    String signingPassword = findProperty("signingPassword")
    if (signingKey && signingPassword) {
        useInMemoryPgpKeys(signingKey, signingPassword)
        sign publishing.publications.maven
    }
}
