String getReleaseVersion() {
    def releaseVersion
    file("core/java/src/net/i2p/CoreVersion.java").readLines().findAll({ line ->
        line.contains("public final static String VERSION")
    }).first().eachMatch('.*"([^"]+)";', {
        releaseVersion = it[1]
    })
    releaseVersion
}

String getBuildVersion() {
    def buildVersion
    file("router/java/src/net/i2p/router/RouterVersion.java").readLines().findAll({ line ->
        line.contains("public final static long BUILD")
    }).first().eachMatch('.*=\\s+([0-9]+);', {
        buildVersion = it[1]
    })
    buildVersion
}

String getBuildExtra() {
    def buildExtra
    file("router/java/src/net/i2p/router/RouterVersion.java").readLines().findAll({ line ->
        line.contains("public final static String EXTRA")
    }).first().eachMatch('.*"(.*)";', {
        buildExtra = it[1]
    })
    buildExtra
}

String getBuiltBy() {
    def builtBy = ""
    def overrideProps = file("override.properties")
    if (overrideProps.exists()) {
        overrideProps.readLines().findAll({ line ->
            line.contains("build.built-by")
        }).first().eachMatch('.*=(.*)', {
            builtBy = it[1]
        })
    }
    builtBy
}

String compat(String src) {
    if (src.contains('.')) {
        src.substring(src.lastIndexOf('.') + 1)
    } else {
        src
    }
}

String getWorkspaceVersion() {
    "git" // TODO: extract revision
}


def releaseVersion = getReleaseVersion()
def buildVersion = getBuildVersion()
def buildExtra = getBuildExtra()
def fullVersion = "$releaseVersion-$buildVersion$buildExtra"

def builtBy = getBuiltBy()
def workspaceVersion = getWorkspaceVersion()

subprojects {
    apply plugin: 'java'
    apply plugin: 'jacoco'

    repositories {
        jcenter()
    }

    dependencies {
        // https://stackoverflow.com/questions/44493378/whats-the-difference-between-api-api-and-compile-in-gradle
        testImplementation 'junit:junit:4.+'
        testImplementation 'org.hamcrest:hamcrest-library:1.3'
        testImplementation 'org.mockito:mockito-core:2.5.0'
    }



    sourceCompatibility = 1.8
    targetCompatibility = 1.8

    jar {
        // Empty attributes are set by each project. They are initialized
        // here in order to create a defined ordering of the attributes.
        manifest {
            attributes 'Specification-Title': ''
            attributes 'Specification-Version': "$releaseVersion"
            attributes 'Specification-Vendor': 'The I2P Project https://geti2p.net/'
            attributes 'Implementation-Title': ''
            attributes 'Implementation-Version': "$fullVersion"
            attributes 'Implementation-Vendor': 'The I2P Project https://geti2p.net/'
            attributes 'Built-By': "$builtBy"
            attributes 'Build-Date': 'reproducible'
            attributes 'Base-Revision': "$workspaceVersion"
            attributes 'Workspace-Changes': ''
            attributes 'X-Compile-Source-JDK': "$sourceCompatibility"
            attributes 'X-Compile-Target-JDK': "$targetCompatibility"
        }
    }

    tasks.withType(AbstractArchiveTask) {
        preserveFileTimestamps = false
        reproducibleFileOrder = true
        doLast {
            stripJar(it.archivePath)
        }
    }
}

task codeCoverageReport(type: JacocoReport) {
    dependsOn(subprojects.test)

    jacocoClasspath = project(':core').configurations.jacocoAnt
    additionalSourceDirs.from(files(subprojects.sourceSets.main.allSource.srcDirs))
    sourceDirectories.from(files(subprojects.sourceSets.main.allSource.srcDirs))
    classDirectories.from(files(subprojects.sourceSets.main.output))
    executionData.from(files(subprojects.jacocoTestReport.executionData))

    // > The value for this file collection is final and cannot be changed.
    //doFirst {
    //    executionData = files(executionData.findAll { it.exists() })
    //}

    reports {
        // https://stackoverflow.com/questions/73546718/changing-enabled-to-required-throws-an-error-in-gradle
        xml.required.set(true)
        xml.destination file("${buildDir}/reports/jacoco/report.xml")
        html.required.set(true)
        html.destination file("${buildDir}/reports/jacoco/html")
    }
}

apply from: file('gradle/update.gradle')

import java.util.jar.*
void stripJar(File file) {
    if (file.getName().endsWith('.tar'))
        return
    println "stripping $file"
    File newFile = new File(file.parent, 'tmp-' + file.name)
    newFile.withOutputStream { fout ->
        JarOutputStream out = new JarOutputStream(fout)
        JarFile jf = new JarFile(file)
        jf.entries().unique {it.name}.sort {it.name}.each {
            def copy = new JarEntry(it.name)
            copy.time = 1001
            out.putNextEntry(copy)
            out << jf.getInputStream(it)
        }
        out.finish()
    }
    newFile.renameTo file
}
