import groovy.json.JsonSlurper
import kcauldron.CreateChangelog
import kcauldron.InstallBundle
import kcauldron.VersionParser

buildscript {
    repositories {
        maven {
            name 'prok'
            url 'https://repo.prok.pw/'
        }
        maven {
            name 'forge'
            url 'http://files.minecraftforge.net/maven'
        }
        mavenCentral()
    }
    dependencies {
        classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
    }
}

tasks.whenTaskAdded {
    if (it.name.startsWith('publish')) it.dependsOn 'preparePublication'
}

apply plugin: 'maven'
apply plugin: 'cauldron'
apply plugin: 'maven-publish'
apply plugin: 'signing'

repositories {
    clear()
    maven {
        name 'prok'
        url 'https://repo.prok.pw/'
    }
    maven {
        name 'forge'
        url 'http://files.minecraftforge.net/maven'
    }
    maven {
        name 'minecraft'
        url 'https://libraries.minecraft.net/'
    }
    mavenCentral()
}

minecraft {
    version = '1.7.10'
    mcpVersion = '9.05'
    mainClass = 'cpw.mods.fml.relauncher.ServerLaunchWrapper'
    tweakClass = 'cpw.mods.fml.common.launcher.FMLTweaker'
    installerVersion = "1.4"
    srgExtra "PK: org/bukkit/craftbukkit org/bukkit/craftbukkit/v1_7_R4"
}

group = 'pw.prok'

ext.buildInfoCached = null;

def buildInfo(String key) {
    if (!buildInfoCached) {
        if (project.hasProperty('officialBuild')) {
            buildInfoCached = new JsonSlurper().parse(new URL("https://api.prok.pw/repo/version/${group}/${name}"))
        } else {
            buildInfoCached = [
                    nextBuildNumber: 'UNOFFICIAL',
                    version        : 'NONE'
            ]
        }
    }
    return key ? buildInfoCached[key] : buildInfoCached;
}

ext.gitInfoCached = null;

def gitInfo(String key) {
    if (!gitInfoCached) {
        if (file('.git').exists()) {
            gitInfoCached = [
                    hash    : ['git', 'log', "--format=%h", '-n', '1'].execute().text.trim(),
                    fullHash: ['git', 'log', "--format=%H", '-n', '1'].execute().text.trim(),
                    branch  : System.getenv("CI_BUILD_REF_NAME") ?: ['git', 'symbolic-ref', '--short', 'HEAD'].execute().text.trim(),
                    message : ['git', 'log', "--format=%B", '-n', '1'].execute().text.trim()
            ]
        } else {
            gitInfoCached = [
                    hash    : 'NOT_A_GIT',
                    fullHash: 'NOT_A_GIT',
                    branch  : 'NOT_A_GIT',
                    message : 'NOT_A_GIT'
            ]
        }
    }
    return key ? gitInfoCached[key] : gitInfoCached;
}

ext.mcVersion = "1.7.10"
ext.forgeVersion = VersionParser.parseForgeRevision(file('src/main/resources/fmlversion.properties'))
ext.revision = project.hasProperty('revision') ? project.getProperty('revision') : buildInfo('nextBuildNumber')
version = "${mcVersion}-${forgeVersion}.${revision}"
if (project.hasProperty('officialBuild')) println "Updated KCauldron version: ${version}"

launch4j {
    jreMinVersion = '1.6.0'
}

configurations {
    compile.extendsFrom exported
    libraries
    bootstrap
}

dependencies {
    bootstrap 'pw.prok:KBootstrap:0.1.+'

    libraries 'net.minecraft:launchwrapper:1.12@jar'
    libraries 'org.ow2.asm:asm-all:5.0.3'
    libraries 'com.typesafe.akka:akka-actor_2.11:2.3.3'
    libraries 'com.typesafe:config:1.2.1'
    libraries 'org.scala-lang:scala-actors-migration_2.11:1.1.0'
    libraries 'org.scala-lang:scala-compiler:2.11.1'
    libraries 'org.scala-lang.plugins:scala-continuations-library_2.11:1.0.2'
    libraries 'org.scala-lang.plugins:scala-continuations-plugin_2.11.1:1.0.2'
    libraries 'org.scala-lang:scala-library:2.11.1'
    libraries 'org.scala-lang:scala-parser-combinators_2.11:1.0.1'
    libraries 'org.scala-lang:scala-reflect:2.11.1'
    libraries 'org.scala-lang:scala-swing_2.11:1.0.1'
    libraries 'org.scala-lang:scala-xml_2.11:1.0.2'
    libraries 'net.sf.jopt-simple:jopt-simple:4.7'
    libraries 'lzma:lzma:0.0.1'
    libraries 'org.yaml:snakeyaml:1.9'
    libraries 'commons-lang:commons-lang:2.6'
    libraries 'org.avaje:ebean:2.7.3'
    libraries 'jline:jline:2.6'
    libraries 'net.md-5:SpecialSource:1.7-SNAPSHOT'
    libraries 'net.sourceforge.argo:argo:2.25'
    libraries 'org.fusesource.jansi:jansi:1.8'
    libraries 'com.googlecode.json-simple:json-simple:1.1'
    libraries 'org.xerial:sqlite-jdbc:3.7.2'
    libraries 'mysql:mysql-connector-java:5.1.14'
    libraries 'javax.persistence:persistence-api:1.0.2'
    libraries 'net.minecraft:server:1.7.10'
    libraries 'pw.prok:KImagine:0.1.12@jar'
    libraries 'org.apache.httpcomponents:httpclient:4.4.1'
}

packageUniversal {
    from { configurations.exported.collect { it.isDirectory() ? it : zipTree(it) } }
}

def String repeat(String string, int times) {
    StringBuilder builder = new StringBuilder(string.length() * times)
    times.times { builder.append(string) }
    builder as String
}

def generateClasspath(boolean legacy = false) {
    def classpath = ''
    configurations.libraries.resolvedConfiguration.resolvedArtifacts.collect { it.moduleVersion.id }.each {
        def jar = "${it.group.replace('.', '/')}/${it.name}/${it.version}/${it.name}-${it.version}.jar"
        classpath += " ${legacy ? 'libraries/' : repeat('../', (group as String).split('\\.').length + 2)}${jar}"
    }
    return classpath.trim()
}

def generateManifest(boolean legacy = false) {
    [
            'KCauldron-Git-Branch'  : gitInfo('branch'),
            'KCauldron-Git-Hash'    : gitInfo('fullHash'),
            'KCauldron-Group'       : project.group,
            'KCauldron-Channel'     : project.name,
            'KCauldron-Version'     : project.version,
            'KCauldron-Legacy'      : legacy,
            'Implementation-Vendor' : 'Prototik',
            'Implementation-Title'  : project.name,
            'Implementation-Version': project.version,
            'Specification-Vendor'  : 'Bukkit Team',
            'Specification-Title'   : 'Bukkit',
            'Specification-Version' : '1.7.10-R0.1-SNAPSHOT',
            'Forge-Version'         : VersionParser.parseForgeVersion(file('forge/src/main/java/net/minecraftforge/common/ForgeVersion.java'), file('src/main/resources/fmlversion.properties')),
            'TweakClass'            : 'cpw.mods.fml.common.launcher.FMLTweaker',
            'Main-Class'            : 'cpw.mods.fml.relauncher.ServerLaunchWrapper',
            'Class-Path'            : generateClasspath(legacy)
    ]
}

tasks.packageUniversal {
    classifier = 'server'
    setManifest {}
    manifest.attributes(generateManifest(true))
}

task jar(type: Jar, dependsOn: packageUniversal) {
    destinationDir file("${buildDir}/distributions")
    from zipTree(tasks.packageUniversal.archivePath)
    manifest.attributes(generateManifest())
}

tasks.createChangelog.onlyIf { false }
tasks.packageInstaller.onlyIf { false }

task packageChangelog(type: CreateChangelog) {
    onlyIf { project.hasProperty('officialBuild') }
    classifier = 'changelog'
    extension = 'txt'
    oldChangelogUrl = "https://repo.prok.pw/${project.group.replace('.', '/')}/${project.name}/${buildInfo('version')}/${project.name}-${buildInfo('version')}-changelog.txt"
    hash = gitInfo('hash')
    message = gitInfo('message')
    version = project.version
}

task bundleStub(type: Jar) {
    classifier = 'stub'
    manifest.attributes([
            'Main-Class': 'cpw.mods.fml.relauncher.ServerLaunchWrapper',
            'Class-Path': "bin/${project.group.replace('.', '/')}/${project.name}/${project.version}/${project.name}-${project.version}.jar"
    ])
}

task installBundle(type: InstallBundle, dependsOn: jar) {
    serverJar tasks.jar.archivePath
    bootstrapClasspath configurations.bootstrap
    bootstrapMain 'pw.prok.bootstrap.Main'
}

task packageBundle(type: Zip, dependsOn: installBundle) {
    classifier = 'bundle'
    from fileTree(installBundle.installLocation)
    from bundleStub
    rename bundleStub.archiveName, 'KCauldron.jar'
}

task signJars(type: Sign, dependsOn: [packageUniversal, packageChangelog, packageBundle, jar, 'generatePomFileForMavenPublication']) {
    sign packageUniversal
    sign packageChangelog
    sign packageBundle
    sign jar
}

task signPom(type: Sign, dependsOn: 'generatePomFileForMavenPublication') {
    outputs.upToDateWhen { false }
    sign file("${buildDir}/publications/maven/pom-default.xml")
}

task preparePublication(dependsOn: [signJars, signPom]) {}

def getPomSignature = {
    return project.tasks.signPom.signatureFiles.collect { it }[0]
}

def getSignatureFiles = {
    def allFiles = project.tasks.signJars.signatureFiles.collect { it }
    def signedServer = allFiles.find { it.name.contains('-server') }
    def signedChangelog = allFiles.find { it.name.contains('-changelog') }
    def signedBundle = allFiles.find { it.name.contains('-bundle') }
    def signedJar = (allFiles - [signedServer, signedChangelog, signedBundle])[0]
    return [
            [archive: signedServer, classifier: 'server', extension: 'jar.asc'],
            [archive: signedChangelog, classifier: 'changelog', extension: 'txt.asc'],
            [archive: signedBundle, classifier: 'bundle', extension: 'zip.asc'],
            [archive: signedJar, classifier: null, extension: 'jar.asc']
    ]
}

publishing {
    repositories {
        maven {
            name 'ProK'
            url 'https://repo.prok.pw/'
            credentials {
                username project.hasProperty('prokRepoUsername') ? prokRepoUsername : null
                password project.hasProperty('prokRepoPassword') ? prokRepoPassword : null
            }
        }
    }

    publications {
        maven(MavenPublication) {
            getSignatureFiles().each { signature ->
                artifact(signature.archive) {
                    classifier = signature.classifier
                    extension = signature.extension
                }
            }
            artifact(getPomSignature()) {
                classifier = null
                extension = 'pom.asc'
            }
            artifact packageUniversal
            artifact packageChangelog
            artifact packageBundle
            artifact jar
        }
    }
}

tasks.generateProjectCauldron << {
    def file = new File('eclipse/cauldron/build.gradle')
    file.append('''
repositories {
    clear()
    maven {
        name 'prok'
        url 'https://repo.prok.pw/'
    }
    maven {
        name 'forge'
        url 'http://files.minecraftforge.net/maven'
    }
    maven {
        name 'minecraft'
        url 'https://libraries.minecraft.net/'
    }
    mavenCentral()
}
dependencies {
''')
    configurations.libraries.resolvedConfiguration.resolvedArtifacts.collect { it.moduleVersion.id }.each { module ->
        if (['net.minecraft:server:', 'org.ow2.asm:asm-all'].findAll { (module as String).startsWith it }.size() > 0) {
            return
        }
        file.append("    compile '${module}'\n")
    }
    file.append('}')
}

task resolveAllDependencies {
    doLast {
        configurations.each { it.resolve() }
    }
}