import org.apache.tools.ant.filters.ReplaceTokens
import de.undercouch.gradle.tasks.download.Download

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.akhikhl.gretty:gretty:+"
    }
}

plugins {
    id "net.saliman.properties" version "1.4.4"
    id "org.sonarqube" version "2.2"
    id 'org.springframework.boot' version '1.5.2.RELEASE'
    id "de.undercouch.download" version "3.1.2"
    id "com.github.ManifestClasspath" version "0.1.0-RELEASE"
}

group "com.epam"

// >>>>> building for different profiles
// >>>>> For configuration use -Pprofile=profile_name with run ('dev' is used by default)
loadConfiguration()

def loadConfiguration() {
    def profile = hasProperty("profile") ? profile : "dev"
    def database = hasProperty("database") ? database : "h2"
    def buildNumber =  hasProperty("buildNumber") ? buildNumber : ""
    project.ext.setProperty("profile", profile)
    project.ext.setProperty("database", database)
    project.ext.setProperty("buildNumber", buildNumber)
    if (profile == "jar") {
        tasks.withType(War).all { it.enabled = false }
        apply plugin: "java"
        jar {
            archiveName "catgenome.jar"
        }
    } else bootRepackage {
        enabled = false
        apply plugin: "war"
        war {
            archiveName "catgenome.war"
        }
    }
}

apply from: "profiles.gradle"

// >>>>> applied plugins

apply plugin: "java"
apply plugin: "application"
apply plugin: "checkstyle"
apply plugin: "pmd"
apply plugin: "jacoco"

test {
    jvmArgs = ["-XX:MaxDirectMemorySize=7937m"]
}

// >>>>> defines external project properties, e.g. external dependencies versions
ext {
    versionSlf4j = "1.7.5"
    versionJackson = "2.12.5"
    versionSpring = "4.3.7.RELEASE"
    versionJayWayJsonPath = "2.7.0"
    versionSpringSecurity = "4.2.2.RELEASE"
    versionJUnit = "4.12"
    versionUnitils = "3.4.2"
    versionJavaXServlet = "3.1.0"
    versionMockito = "1.10.19"
    versionLucene = "6.6.0"
}

// >>>>> repositories that should be used to find any external dependencies
repositories {
    mavenCentral()
    maven {
        url "https://jitpack.io"
    }
    maven {
        url "http://www.biopax.org/m2repo/releases/"
    }
    flatDir {
        dirs 'lib'
    }
}

ext['jetty.version'] = '9.4.8.v20171121'
ext['log4j2.version'] = '2.17.1'

// >>>>> external dependencies used to compile and/or run application
dependencies {
    // >>>>> dependencies used to compile application and include into artifact
    // Spring Framework
    configurations {
        all*.exclude module: 'spring-boot-starter-logging'
        all*.exclude group: 'ch.qos.logback'
        all*.exclude module: 'log4j-slf4j-impl'
    }
    compile group: "org.springframework", name: "spring-jdbc", version: project.ext.versionSpring
    compile group: "org.springframework", name: "spring-context", version: project.ext.versionSpring
    compile group: "org.springframework", name: "spring-context-support", version: project.ext.versionSpring
    compile group: 'org.springframework', name: 'spring-aop', version: project.ext.versionSpring

    compile group: "org.springframework.security", name: "spring-security-core", version: versionSpringSecurity
    compile group: "org.springframework.security", name: "spring-security-web", version: versionSpringSecurity
    compile group: "org.springframework.security", name: "spring-security-config", version: versionSpringSecurity
    compile group: 'org.springframework.security', name: 'spring-security-acl', version: versionSpringSecurity

    compile group: "org.springframework.security.oauth", name: "spring-security-oauth2", version: "2.0.12.RELEASE"
    compile group: "org.springframework.security.extensions", name: "spring-security-saml2-core", version: "1.0.2.RELEASE"

    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    compile("org.springframework.boot:spring-boot-devtools")

    if (profile == "jar") {
        compile('org.apache.tomcat.embed:tomcat-embed-jasper')
        compile("org.springframework.boot:spring-boot-starter-tomcat")
    } else {
        providedRuntime('org.apache.tomcat.embed:tomcat-embed-jasper')
        providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
    }

    // Jackson
    compile group: "com.fasterxml.jackson.core", name: "jackson-core", version: versionJackson //project.ext.versionJackson
    compile group: "com.fasterxml.jackson.core", name: "jackson-databind", version:  versionJackson //project.ext.versionJackson
    compile group: "com.fasterxml.jackson.core", name: "jackson-annotations", version: versionJackson //project.ext.versionJackson
    compile group: "com.fasterxml.jackson.dataformat", name: "jackson-dataformat-xml", version: versionJackson //project.ext.versionJackson
    compile group: "com.squareup.retrofit2", name: "converter-jackson", version: "2.7.2"

    // Apache Commons
    compile group: "commons-io", name: "commons-io", version: "2.4"
    compile group: "org.apache.commons", name: "commons-lang3", version: "3.0"
    compile group: "org.apache.commons", name: "commons-collections4", version: "4.1"
    compile group: "commons-validator", name: "commons-validator", version: "1.5.0"
    compile group: 'org.apache.commons', name: 'commons-math3', version: '3.6.1'
    // Logging
    compile group: "org.apache.logging.log4j", name: "log4j", version: "2.17.1"
    compile group: "org.slf4j", name: "slf4j-api", version: project.ext.versionSlf4j
    compile group: "org.slf4j", name: "slf4j-log4j12", version: project.ext.versionSlf4j
    // Samtools
    compile group: "com.github.samtools", name: "htsjdk", version: "2.2.4"
    compile "org.xerial.snappy:snappy-java:1.0.3-rc3"
    // Swagger
    compile group: "org.webjars", name: "swagger-ui", version: "2.0.24"
    compile group: "com.mangofactory", name: "swagger-springmvc", version: "1.0.2"
    // H2 Database Engine & Connection pool
    compile group: "com.mchange", name: "c3p0", version: "0.9.5.1"
    compile group: "com.h2database", name: "h2", version: "1.3.176"
    compile group: "org.aspectj", name: "aspectjweaver", version: "1.8.8"
    compile group: 'org.postgresql', name: 'postgresql', version: "9.4-1206-jdbc4"
    // Flyway database migration to update embedded database when application starts
    compile group: "org.flywaydb", name: "flyway-core", version: "3.2.1"
    //Amazon s3
    compile group: "com.amazonaws", name: "aws-java-sdk-s3", version: "1.11.704"
    compile group: "com.amazonaws", name: "aws-java-sdk-sts", version: "1.11.704"

    // Azure Storage Blob
    compile group: "com.azure", name: "azure-storage-blob", version: "12.14.0"
    compile group: "com.azure", name: "azure-identity", version: "1.4.4"
    compile group: 'io.projectreactor', name: 'reactor-core', version: '3.5.3'

    compile 'commons-fileupload:commons-fileupload:1.3.1'

    //Ehcache
    compile group: "net.sf.ehcache", name: "ehcache", version: "2.10.1"
    // Lucene
    compile group: "org.apache.lucene", name:"lucene-core", version: versionLucene
    compile group: "org.apache.lucene", name:"lucene-queryparser", version: versionLucene
    compile group: "org.apache.lucene", name:"lucene-analyzers-common", version: versionLucene
    compile group: "org.apache.lucene", name:"lucene-grouping", version: versionLucene
    compile group: "org.apache.lucene", name:"lucene-facet", version: versionLucene
    compile group: "org.apache.lucene", name:"lucene-backward-codecs", version: versionLucene

    //security
    compile 'com.auth0:java-jwt:3.1.0'

    // lombok
    compileOnly "org.projectlombok:lombok:1.16.16"

    //hadoop
    compile group: "org.apache.hadoop", name:"hadoop-client", version: "2.2.0"

    compile(group: "org.jetbrains.bio", name: "big", version: "0.9.1") {
        exclude group: "com.github.samtools", module: "htsjdk"
    }

    // biojava
    compile group: "org.biojava", name:"biojava-genome", version: "4.2.0"
    compile group: "org.biojava", name:"biojava-structure", version: "4.2.0"

    // newick format
    compile group: "com.github.qurben", name: "libnewicktree", version: "1.0"

    // igv
    compile group: "com.github.igvteam", name: "igv", version: "v2.6.3"

    // sbgn format
    compile group: "org.sbgn", name: "libsbgn", version: "0.2"

    //  BioPAX
    compile group: "org.biopax.paxtools", name: "paxtools-core", version: "5.1.0"
    compile group: "org.biopax.paxtools", name: "sbgn-converter", version: "5.0.0"
    compile group: "pathwaycommons", name: "chilay-sbgn", version: "3.0.0"

    //LLM
    compile group: "com.azure", name: "azure-ai-openai", version: "1.0.0-beta.2"
    compile group: "com.google.cloud", name: "google-cloud-aiplatform", version: "3.37.0"
    compile group: 'com.google.code.gson', name: 'gson', version: '2.10.1'

    compile group: 'com.google.apis', 'name':'google-api-services-customsearch', version: 'v1-rev20240103-2.0.0'
    compile group: 'com.google.http-client', name: 'google-http-client-jackson2', version: '1.44.1'

    //Excel
    compile group: "org.apache.poi", name: "poi", version: "3.16"
    compile group: "org.apache.poi", name: "poi-ooxml", version: "3.16"

//    CSV
    compile group: "com.opencsv", name: "opencsv", version: "5.8"

    // >>>>> dependencies used to compile tests; in fact no need to include them into artifact
    testCompile("org.springframework.boot:spring-boot-starter-test")
    testCompile group: "org.unitils", name: "unitils-core", version: project.ext.versionUnitils
    testCompile group: "javax.servlet", name: "javax.servlet-api", version: project.ext.versionJavaXServlet
    testCompile group: "com.jayway.jsonpath", name: "json-path", version: project.ext.versionJayWayJsonPath
    testCompile group: "com.jayway.jsonpath", name: "json-path-assert", version: project.ext.versionJayWayJsonPath
    testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.4.8.v20171121'
    testCompile group: "org.springframework.security", name: "spring-security-test", version: versionSpringSecurity

    testRuntime group: "javax.transaction", name: "jta", version: "1.1"
}

// >>>>> To configure Run/Debug with Local Tomcat on dev environment an exploded WAR archive should be
// >>>>> created. See also: https://issues.gradle.org/browse/GRADLE-1445
if (profile != "jar") {
    task warExploded(type: Sync) {
        into "$buildDir/catgenome"
        with war
    }
    war.dependsOn warExploded
}

// >>>>> processes profiles
processResources.dependsOn copyConfiguration
processTestResources {
    filesNotMatching("**/templates/**") {  // To exclude binary files, because they are being broken by filtering
        filter(ReplaceTokens, tokens: project.filterTokens)
    }
}

// >>>>> configuration for pmd plugin
pmd {
    //ruleSetConfig = resources.text.fromFile("config/pmd/pmd-ruleset.xml")
    ruleSetFiles = files("config/pmd/pmd-ruleset.xml", "config/pmd/pmd-ruleset-feature-index-manager.xml")
}

checkstyle {
    toolVersion = "7.2"
}

def excludePattern = 'VgPb'
def excludePatternAntStyle = '**/' + excludePattern + '*'

tasks.withType(Checkstyle) {
    exclude excludePatternAntStyle
}
tasks.withType(Pmd) {
    exclude excludePatternAntStyle
}

def escape(String s) {
    return s.replace("\\", "\\\\")
}

//Distributions
//distribution properties
def appName = 'ngb-server'
def springBootlauncherClass = 'org.springframework.boot.loader.JarLauncher'
def springBootJarName = 'catgenome.jar'
def ngbJvmOptions = ["-Xms512m", "-Xmx2g"]
def jreURL = "http://download.oracle.com/otn-pub/java/jdk/8-b132/"
def windowsJre = "jre-8-windows-x64.tar.gz"
def linuxJre = "jre-8-linux-x64.tar.gz"

startScripts {
    applicationName = appName
    mainClassName = springBootlauncherClass
    classpath = files(springBootJarName)
    defaultJvmOpts = ngbJvmOptions
}

task zip(type: Zip) {
    dependsOn bootRepackage
    from('build/libs/') {
        include '**/*.jar'
        into('lib')
    }
    from('build/scripts') {
        into('bin')
    }
    baseName = appName
    archiveName = 'ngb-server.zip'
}

task tar(type: Tar) {
    dependsOn bootRepackage
    from('build/libs/') {
        include '**/*.jar'
        into('lib')
    }
    from('build/scripts') {
        into('bin')
    }
    baseName = appName
    archiveName = 'ngb-server.tgz'
    extension = 'tgz'
    compression = Compression.GZIP
}

//Windows Distribution
task customStartScriptsWin(type: CreateStartScripts) {
    applicationName = appName
    mainClassName = springBootlauncherClass
    classpath = files(springBootJarName)
    defaultJvmOpts = ngbJvmOptions
    outputDir = file("$buildDir/scripts")
    doLast {
        windowsScript.text = windowsScript.text.replace("set JAVA_EXE=%JAVA_HOME%/bin/java.exe",
                "set JAVA_EXE=%APP_HOME%/jre1.8.0/bin/java.exe")
        unixScript.text = unixScript.text.replace("exec \"\$JAVACMD\" \"\$@\"",
                "exec \"\$APP_HOME/jre1.8.0/bin/java\" \"\$@\"")
    }
}

task downloadJreWin(type: Download) {
    dependsOn bootRepackage
    src jreURL + windowsJre
    dest "$buildDir/downloads/$windowsJre"
    header 'Cookie', 'oraclelicense=accept-securebackup-cookie'
    overwrite true
}

task bundleWindows(type: Zip) {
    dependsOn downloadJreWin
    dependsOn customStartScriptsWin, bootRepackage
    from(tarTree(resources.gzip("$buildDir/downloads/$windowsJre"))) {
    }

    from("$buildDir/downloads/jre1.8.0") {
    }

    from("$buildDir/libs") {
        include '**/*.jar'
        into('lib')
    }

    from("$buildDir/scripts") {
        into('bin')
    }

    baseName = appName
    archiveName = 'ngb-server-windows.zip'
}

//Linux Distribution

task customStartScriptsLinux (type: CreateStartScripts) {
    applicationName = appName
    mainClassName = springBootlauncherClass
    classpath = files(springBootJarName)
    defaultJvmOpts = ngbJvmOptions
    outputDir = file("$buildDir/scripts")
    doLast {
        unixScript.text = unixScript.text.replace("exec \"\$JAVACMD\" \"\$@\"",
                "exec \"\$APP_HOME/jre1.8.0/bin/java\" \"\$@\"")
    }
}

task downloadJreLinux(type: Download) {
    dependsOn bootRepackage
    src jreURL + linuxJre
    dest "$buildDir/downloads/$linuxJre"
    header 'Cookie', 'oraclelicense=accept-securebackup-cookie'
    overwrite true
}

task bundleLinux(type: Tar) {
    dependsOn downloadJreLinux
    dependsOn customStartScriptsLinux, bootRepackage
    from (tarTree(resources.gzip("$buildDir/downloads/$linuxJre"))) {
    }

    from("$buildDir/downloads/jre1.8.0") {
    }

    from("$buildDir/libs") {
        include '**/*.jar'
        into('lib')
    }

    from("$buildDir/scripts/ngb-server") {
        into('bin')
    }

    baseName = appName
    archiveName = 'ngb-server-linux.tgz'
    extension = 'tgz'
    compression = Compression.GZIP
}

distTar {
    enabled = false
}

distZip {
    enabled = false
}

jacocoTestReport {
    reports {
        xml.enabled true
        html.enabled false
    }
}
