plugins {
    id 'java'
    id 'jacoco'
    id 'application'
    id 'maven-publish'
    id 'signing'
}
// name is set in settings.gradle
group 'io.github.andrewquijano'
version = System.getenv("VERSION") ?: "2.0.0"

repositories {
    mavenCentral()
}

// https://www.baeldung.com/gradle-sourcecompatiblity-vs-targetcompatibility
java {
    withJavadocJar()
    withSourcesJar()
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
}

dependencies {
    // Only use full log4j API in testing, but in deployment use API for others to use the library
    // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
    testImplementation 'org.apache.logging.log4j:log4j-core:2.24.3'
    testImplementation 'junit:junit:4.13.2'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.0-M1'
    // https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api
    implementation 'org.apache.logging.log4j:log4j-api:2.24.3'
    // https://mvnrepository.com/artifact/commons-io/commons-io
    implementation 'commons-io:commons-io:2.16.1'
    implementation 'org.bouncycastle:bcprov-jdk18on:1.78'
    implementation fileTree(dir: 'libs', include: ['*.jar'])
}

// Commenting because it doesn't work well on TravisCI
test {
    testLogging {
// Make sure output from
// standard out or error is shown
// in Gradle output.
        showStandardStreams = true
    }

    // Set JVM arguments to include your agent
    jvmArgs = [
            '-javaagent:libs/InstrumentationAgent.jar' // Change this to your agent JAR path
    ]
}

// This library was built for Java 8 so it can be imported into Android as well.
// If you want to use a later version of Java, this should help point what to tweak.
gradle.projectsEvaluated {
    tasks.withType(JavaCompile).tap {
        configureEach {
            options.compilerArgs << "-Xlint:deprecation,unchecked"
        }
    }
}

jacocoTestReport {
    reports {
        xml.required=true
        html.required=true
    }
}

check.dependsOn jacocoTestReport

application {
    mainClass.set(project.findProperty("chooseRole").toString())
}

// To create the JAR file with 'gradlew jar'
tasks.named('jar') {
    archiveFileName = "${project.name}-${project.version}.jar"
    manifest {
        attributes(
                'Implementation-Title': project.name,
                'Implementation-Version': System.getenv('VERSION') ?: project.version
        )
    }
}

tasks.register('generateJavadoc', Javadoc) {
    source = sourceSets.main.allJava
    classpath = sourceSets.main.compileClasspath
    options.encoding = 'UTF-8'
    options.memberLevel = JavadocMemberLevel.PUBLIC
    options.addStringOption('Xdoclint:none', '-quiet')
    options.docTitle = 'Homomorphic Encryption API'
}

// Define a task to run your Java application with the agent
tasks.register('runWithAgent', JavaExec) {
    classpath = sourceSets.main.runtimeClasspath

    // Set JVM arguments to include your agent
    jvmArgs = [
            '-javaagent:libs/InstrumentationAgent.jar'
    ]
}

// Configure the 'run' task to depend on 'runWithAgent'
tasks.run.dependsOn('runWithAgent')

// This is for publishing the library to Maven Central
publishing {
    publications {
        register("mavenJava", MavenPublication) {
            from components.java

            pom {
                name.set('Ciphercraft')
                description.set('This is a library that implements partially homomorphic encryption algorithms: ' +
                        'Paillier, ElGamal, and DGK. This also implements various two-party protocols for secure ' +
                        'computation such as multiplication, division and comparison')
                url.set('https://github.com/adwise-fiu/Ciphercraft')

                licenses {
                    license {
                        name.set('MIT License')
                        url.set('https://opensource.org/licenses/MIT')
                    }
                }

                developers {
                    developer {
                        id.set('AndrewQuijano')
                        name.set('Andrew Quijano')
                        email.set('andrew.quijano@nyu.edu')
                        roles.add('Lead Developer')
                    }
                }

                organization {
                    name.set('New York University')
                    url.set('https://www.nyu.edu')
                }

                scm {
                    connection.set('scm:git:git://github.com/adwise-fiu/Ciphercraft.git')
                    developerConnection.set('scm:git:ssh://github.com:adwise-fiu/Ciphercraft.git')
                    url.set('https://github.com/adwise-fiu/Ciphercraft')
                }
            }
        }
    }
}

// Update this file, ~/.gnupg/dirmngr.conf
// and add this line to the file 'keyserver hkps://keyserver.ubuntu.com'
// then run 'gpg --send-keys YOUR_KEY_ID'
signing {
    // Point to the key file on your machine, used for local testing
    def signingKeyFile = findProperty("signingKeyFile") ?: System.getenv("SIGNING_KEY_FILE")
    // gpg --armor --export-secret-keys YOUR_KEY_ID, export the key into a secret
    def signingKey = findProperty("signingKey") ?: System.getenv("SIGNING_KEY")
    // If no property or environment variable is found, it will be empty password
    def signingPassword = findProperty("signingPassword") ?: System.getenv("SIGNING_PASSWORD") ?: ""

    if (signingKeyFile) {
        println("Reading signing key from file: $signingKeyFile")
        def signingKey_content = new File(signingKeyFile.toString()).text
        useInMemoryPgpKeys(signingKey_content.toString(), signingPassword.toString())
        publishing.publications.named("mavenJava").configure { publication ->
            signing.sign(publication)
        }
    }
    else {
        println("No signing key file found, will attempt to use in-memory key")
        if (signingKey) {
            useInMemoryPgpKeys(signingKey.toString(), signingPassword?.toString())
            publishing.publications.named("mavenJava").configure { publication ->
                signing.sign(publication)
            }
        }
        else {
            println("No signing key found. Skipping signing.")
        }
    }
}
