import java.security.MessageDigest

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}

configurations {
    provided
    compile
}

apply plugin: 'java'
apply plugin: 'maven-publish'

repositories {
    flatDir { dirs uri("${projectDir}/lib") }
    maven {
        url 'https://mvn.freenetproject.org'
        metadataSources {
            artifact()
        }
    }
    mavenCentral()
}

sourceSets {
    main.compileClasspath += configurations.provided
    test.compileClasspath += configurations.provided
}

def version_buildir = file("$projectDir/build/tmp/compileVersion/")
def version_src = 'freenet/node/Version.java'

sourceSets {
    main {
        java {
            srcDir 'src/'
        }
    }
    test {
        java {
            srcDir 'test/'
        }
    }
}

def gitrev
task buildInfo {
    try {
        def cmd = "git describe --always --abbrev=4 --dirty"
        def proc = cmd.execute([], project.rootDir)
        gitrev = proc.text.trim()
    } catch (IOException ignored) {
        gitrev = "@unknown@"
    }
}

java {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}

tasks.withType(JavaCompile) {
    options.encoding = "UTF-8"
}

tasks.withType(Javadoc) {
    options.encoding = "UTF-8"
}

task generateVersionSource(type: Copy) {
    dependsOn buildInfo
    from(sourceSets.main.java.srcDirs) {
        include version_src
        filter {
            String line -> line.replaceAll('@custom@', gitrev)
        }
    }
    into version_buildir
}

task compileVersion (type: JavaCompile) {
    dependsOn generateVersionSource, compileJava
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    source = version_buildir
    include version_src
    classpath = files(sourceSets.main.compileClasspath, sourceSets.main.output.classesDirs)
    destinationDirectory.set(layout.buildDirectory.dir("java/version/").get())
}

task buildJar(type: Jar) {
    dependsOn compileVersion, processResources
    from(processResources)
    from(compileJava.destinationDirectory) {
        exclude 'freenet/node/Version.class'
        exclude 'freenet/node/Version$1.class'
    }
    from(compileVersion.destinationDirectory)
    preserveFileTimestamps = false
    reproducibleFileOrder = true
    duplicatesStrategy = DuplicatesStrategy.FAIL
    archivesBaseName = "freenet"
    manifest {
        attributes("Permissions": "all-permissions")
        attributes("Application-Name": "Freenet REference Daemon")
        attributes("Required-Ext-Version": 29)
        attributes("Recommended-Ext-Version": 29)
        attributes("Compiled-With": "${System.getProperty('java.version')} (${System.getProperty('java.vendor')})")
        attributes([
                       "Specification-Title": "Freenet",
                       "Specification-Version": "0.7.5",
                       "Specification-Vendor": "freenetproject.org",
                       "Implementation-Title": "Freenet",
                       "Implementation-Version": "0.7.5 ${gitrev}",
                       "Implementation-Vendor": "freenetproject.org",
                   ], "common")
    }
}

jar.enabled = false
jar.dependsOn buildJar

def jars = []
gradle.addListener(new TaskExecutionListener() {
void afterExecute(Task task, TaskState state) {
    if(task in AbstractArchiveTask && task.enabled) {
        jars << task.outputs.files.singleFile
    }
}

void beforeExecute(Task task) { }
})
gradle.addBuildListener(new BuildAdapter() {
    void buildFinished(BuildResult result) {
        if(jars) {
            def hash = {
                File file -> def sha256 = MessageDigest.getInstance('SHA-256')
                file.eachByte(1024 * 4) { buffer, len -> sha256.update(buffer, 0, len) }
                println "SHA-256 of ${file.name}: ${sha256.digest().encodeHex().toString()}"
            }

            jars.each { hash(it) }
        }
    }
})

task copyResourcesToClasses2 {
    inputs.files sourceSets.main.allSource
    outputs.dir layout.buildDirectory.dir("classes/java/main/")
    doLast {
        copy {
            from sourceSets.main.allSource
            into layout.buildDirectory.dir("classes/java/main/")
            include 'freenet/l10n/*properties'
            include 'freenet/l10n/iso-*.tab'
            include 'freenet/clients/http/staticfiles/**'
            include 'freenet/clients/http/templates/**'
            include '../dependencies.properties'
        }
        copy {
            from "${projectDir}/"
            into layout.buildDirectory.dir("classes/java/main/")
            include 'dependencies.properties'
        }
    }
}
processResources.dependsOn copyResourcesToClasses2
compileVersion.dependsOn copyResourcesToClasses2

task copyTestResourcesToClasses2 {
    inputs.files sourceSets.test.allSource
    outputs.dir layout.buildDirectory.dir("classes/java/test/")
    doLast {
        copy {
	    from sourceSets.test.allSource
	    into layout.buildDirectory.dir("classes/java/test/")
            include 'freenet/client/filter/*/**'
            include 'freenet/crypt/ciphers/rijndael-gladman-test-data/**'
            include 'freenet/l10n/*properties'
            include 'freenet/clients/http/templates/**'
        }
    }
}
compileTestJava.dependsOn copyResourcesToClasses2
compileTestJava.dependsOn copyTestResourcesToClasses2

test {
    if(JavaVersion.current() >= JavaVersion.VERSION_1_9) {
        jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED'
        jvmArgs '--add-opens=java.base/java.util=ALL-UNNAMED'
        jvmArgs '--add-opens=java.base/java.io=ALL-UNNAMED'
        jvmArgs '--add-opens=java.base/java.util.zip=ALL-UNNAMED'
    }
    minHeapSize = "128m"
    maxHeapSize = "512m"
    // no inner class
    include 'freenet/**/*Test.class'
    exclude 'freenet/**/*$*Test.class'
    workingDir = layout.buildDirectory.dir("classes/java/test/")
    scanForTestClasses = false
    systemProperties += [
        "test.l10npath_test": "freenet/l10n/",
        "test.l10npath_main": "../main/freenet/l10n/"
//	"test.extensive":
//	"test.verbose":
//	"test.benchmark":
    ]
}

tasks.withType(Test) {
    enableAssertions = false
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId 'org.freenetproject'
            artifactId "fred"
            version gitrev
            from components.java
        }
    }
    repositories {
        maven {
            url "s3://mvn.freenetproject.org/"
            credentials(AwsCredentials) {
                accessKey System.getenv('AWS_ACCESS_KEY_ID')
                secretKey System.getenv('AWS_SECRET_ACCESS_KEY')
            }
        }
    }
}

task copyRuntimeLibs(type: Copy) {
    into "${buildDir}/output/"
    from configurations.runtimeClasspath
    from jar
}
copyRuntimeLibs.dependsOn jar

// In this section you declare the dependencies for your production and test code
dependencies {
    implementation "org.bouncycastle:bcprov-jdk15on:1.59"
    implementation "net.java.dev.jna:jna:4.5.2"
    implementation "net.java.dev.jna:jna-platform:4.5.2"
    implementation "org.freenetproject:freenet-ext:29"
    implementation "io.pebbletemplates:pebble:3.1.5"
    // dependencies of pebble
    implementation "org.unbescape:unbescape:1.1.6.RELEASE"
    implementation "org.slf4j:slf4j-api:1.7.25"

    testImplementation 'junit:junit:4.13.2'
    testImplementation "org.mockito:mockito-core:1.9.5"
    testImplementation "org.hamcrest:hamcrest:3.0"
    testImplementation "org.objenesis:objenesis:1.0"
}

task tar(type: Tar) {
  description = "Build a source release, specifically excluding the build directories and gradle wrapper files"
  compression = Compression.BZIP2

  archiveBaseName = "freenet-sources"

  from(project.rootDir) {
    exclude '**/build'
    exclude 'build'
    exclude '.gradle'
  }

  into(archiveBaseName)

  preserveFileTimestamps = true
  reproducibleFileOrder = true

  // Set destination directory.
  destinationDirectory = file("${project.buildDir}")

  archiveFileName = "${archiveBaseName}.tgz"
  doLast { // generate md5 checksum
    ant.checksum file:"$destinationDirectory/$archiveFileName"
  }
}

javadoc {
    doLast {
        failOnError false
    }
}
