/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
plugins {
  id 'com.eriwen.gradle.js' version '1.12.1'
  id 'com.github.ben-manes.versions' version '0.11.3'
  id 'com.github.hierynomus.license' version '0.11.0'
  id 'com.moowork.node' version '1.2.0'
  id 'me.champeau.gradle.jmh' version '0.4.4'
  id "com.github.spotbugs" version "1.6.4"
}

apply plugin: 'application'
apply plugin: 'checkstyle'
apply plugin: 'jacoco'
apply plugin: 'pmd'

def minJavaVersion = JavaVersion.VERSION_1_8;

allprojects {
  apply plugin: 'java'
  apply plugin: 'idea'
  apply plugin: 'maven-publish'
  apply plugin: 'project-report'

  buildDir = 'dist'

  repositories {
    mavenCentral()
  }

  compileJava {
    sourceCompatibility = minJavaVersion
    targetCompatibility = minJavaVersion
  }

  group 'org.apache.aurora'
  version = file("${rootDir}/.auroraversion").text.trim().toUpperCase()
  if (version.contains('/')) {
    throw new GradleException('''
*******************************************************************************
The application version string read by gradle is invalid.  This is known to
happen when building on Windows, or within vagrant with a Windows host.
You can work around this issue by cloning git _within_ vagrant and building
from there.

For more details, please see https://issues.apache.org/jira/browse/AURORA-1169
*******************************************************************************
''')
  }

  task sourceJar(type: Jar) {
    from sourceSets.main.allJava
  }

  if (project.hasProperty('internalMavenUrl')) {
    publishing {
      repositories {
        maven {
          credentials {
            username = internalMavenUser
            password = internalMavenPass
          }
          url internalMavenUrl
        }
      }
    }
  }

  ext.commonsLangRev = '2.6'
  ext.curatorRev = '2.12.0'
  ext.gsonRev = '2.3.1'
  ext.guavaRev = '23.2-jre'
  ext.guiceRev = '4.1.0'
  ext.httpclientRev = '4.5.2'
  ext.httpcoreRev = '4.4.4'
  ext.asyncHttpclientRev = '2.0.37'
  ext.jacksonRev = '2.5.1'
  ext.jaxRsRev = '2.0'
  ext.junitRev = '4.12'
  ext.logbackRev = '1.2.3'
  ext.nettyRev = '4.0.52.Final'
  ext.protobufRev = '3.5.1'
  ext.resteasyRev = '3.1.4.Final'
  ext.servletRev = '3.1.0'
  ext.slf4jRev = '1.7.25'
  ext.stringTemplateRev = '3.2.1'
  ext.thriftRev = '0.10.0'
  ext.zookeeperRev = '3.4.8'

  configurations.all {
    exclude module: 'junit-dep'
    // We use logback, so we do not want to pull in log4j artifacts.
    exclude module: 'log4j'
    exclude module: 'slf4j-log4j12'

    // ResolutionStrategy needs to be set in the allprojects block otherwise dependent projects
    // will not inherit it. Note that dependencies still need to be specified in a dependencies
    // block - this only affects strategy.
    // See http://forums.gradle.org/gradle/topics/shouldnt-resolutionstrategy-affect-depending-projects-transitive-dependencies
    resolutionStrategy {
      failOnVersionConflict()
      force "com.google.inject:guice:${guiceRev}"
      force "com.google.inject.extensions:guice-multibindings:${guiceRev}"
      force "org.apache.httpcomponents:httpclient:${httpclientRev}"
      force "org.apache.httpcomponents:httpcore:${httpcoreRev}"
      force "com.fasterxml.jackson.core:jackson-annotations:${jacksonRev}"
      force "com.fasterxml.jackson.core:jackson-core:${jacksonRev}"
      force "com.google.code.gson:gson:${gsonRev}"
      force "com.google.guava:guava:${guavaRev}"
      force "com.google.protobuf:protobuf-java:${protobufRev}"
      force "io.netty:netty-handler:${nettyRev}"
      force "junit:junit:${junitRev}"
      force "org.apache.thrift:libthrift:${thriftRev}"
      force "org.apache.zookeeper:zookeeper:${zookeeperRev}"
      force "org.hamcrest:hamcrest-core:1.3"
      force 'org.objenesis:objenesis:2.2'
      force "org.slf4j:slf4j-api:${slf4jRev}"
    }
  }
}

/**
 * This gradle project contains the logic to bootstrap and build the UI bundle using NodeJS.
 * The core logic of UI building is delegated to npm and Webpack. Webpack writes the UI bundle
 * into the resources directory of the Scheduler, so it must be built before the Scheduler.
 */
project(':ui') {
  apply plugin: 'com.moowork.node'
  node {
    download = true
  }

  task test_(type: NpmTask, overwrite: true) {
    inputs.files(fileTree('src'), fileTree('plugin'))
    outputs.files(fileTree('dist'))
    args = ['test']
  }

  task pluginInstall(type: NpmTask) {
    inputs.files(file('plugin/package.json'))
    outputs.files(fileTree('node_modules'))

    args = ['install', 'plugin/']
  }

  task install(type: NpmTask, dependsOn: 'pluginInstall') {
    inputs.files(file('package.json'))
    outputs.files(fileTree('node_modules'))
    // Install into the project dir to sandbox everything under ui/
    args = ['install']
  }

  task lint(type: NpmTask, dependsOn: 'install') {
    inputs.files(fileTree('src'), fileTree('plugin'))
    outputs.files(fileTree('.'))
    args = ['run', 'lint']
  }

  task webpack(type: NodeTask, dependsOn: 'install') {
    inputs.files(fileTree('src'), fileTree('plugin'))
    outputs.files(sourceSets.main.java)
    script = file('node_modules/.bin/webpack')
  }

  tasks.build.dependsOn(lint)
  tasks.build.dependsOn(webpack)
  tasks.build.dependsOn(npm_test)
}
// Make sure UI webpack is run as part of 'processResources --continuous'. Also makes sure when
// building the Scheduler JAR, the JS bundle is built first.
tasks.processResources.dependsOn(':ui:webpack')

project(':commons') {
  apply plugin: 'license'
  license {
    header rootProject.file('config/checkstyle/apache.header')
    strictCheck true
  }

  dependencies {
    compile "com.google.code.gson:gson:${gsonRev}"
    compile "com.google.guava:guava:${guavaRev}"
    compile "com.google.inject:guice:${guiceRev}"
    compile "commons-lang:commons-lang:${commonsLangRev}"
    compile "javax.servlet:javax.servlet-api:${servletRev}"
    compile "javax.ws.rs:javax.ws.rs-api:${jaxRsRev}"
    compile "org.antlr:stringtemplate:${stringTemplateRev}"
    compile "org.apache.zookeeper:zookeeper:${zookeeperRev}"
    compile "org.easymock:easymock:3.4"

    // There are a few testing support libs in the src/main/java trees that use junit - currently:
    //   src/main/java/org/apache/aurora/common/zookeeper/testing
    //   src/main/java/org/apache/aurora/common/testing
    compile "junit:junit:${junitRev}"

    testCompile "junit:junit:${junitRev}"
  }
}

project(':api') {
  apply plugin: org.apache.aurora.build.ThriftPlugin
  apply plugin: org.apache.aurora.build.ThriftEntitiesPlugin

  task checkPython {
    doLast {
      def python27Executable = ['python2.7', 'python'].find { python ->
        try {
          def check = "import sys; sys.exit(0 if sys.version_info >= (2,7) and sys.version_info < (3,) else 1)"
          return [python, "-c", check].execute().waitFor() == 0
        } catch (IOException e) {
          return false
        }
      }

      if (python27Executable == null) {
        throw new GradleException('Build requires Python 2.7.')
      } else {
        thriftEntities.python = python27Executable
      }
    }
  }
  generateThriftEntitiesJava.dependsOn checkPython

  tasks.withType(Jar) {
    baseName "aurora-api"
  }

  publishing {
    publications {
      mavenJava(MavenPublication) {
        from components.java

        artifactId "aurora-api"

        artifact sourceJar {
          classifier "sources"
        }
      }
    }
  }

  thrift {
    version = thriftRev
    resourcePrefix = 'org/apache/aurora/scheduler/gen/client'
  }

  thriftEntities {
    gsonRev = project.gsonRev
    guavaRev = project.guavaRev
    inputFiles = fileTree("src/main/thrift/org/apache/aurora/gen").matching {
      include "**/*.thrift"
    }
  }

  idea {
    module {
      [thrift.genJavaDir, thriftEntities.genJavaDir].each {
        sourceDirs += it
        generatedSourceDirs += it
      }

      // These directories must exist, else the plugin omits them from the
      // generated project. Since this is executed during the configuration
      // lifecycle phase, dependency tasks have not yet run and created
      // the directories themselves.
      // By default, the idea module [1] excludes are set to
      // [project.buildDir, project.file('.gradle')]
      // This has the side-effect of also excluding our generated sources [2].  Due to the way
      // directory exclusion works in idea, you can't exclude a directory and include a child of that
      // directory. Clearing the excludes seems to have no ill side-effects, making it preferable to
      // other possible approaches.
      //
      // [1] http://www.gradle.org/docs/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html
      // [2] http://issues.gradle.org/browse/GRADLE-1174
      excludeDirs = [file(".gradle")]
      [
          "classes",
          "dependency-cache",
          "docs",
          "jacoco",
          "reports",
          "test-results",
          "tmp"
      ].each {
        excludeDirs << file("$buildDir/$it")
      }
    }
  }
}

def generatedDir = "$buildDir/generated-src"
def httpAssetsPath = 'scheduler/assets'

compileJava {
  options.compilerArgs << '-Werror'
  options.compilerArgs << '-Xlint:all'
  // Don't fail for annotations not claimed by annotation processors.
  options.compilerArgs << '-Xlint:-processing'
  // Don't fail for serialVersionUID warnings.
  options.compilerArgs << '-Xlint:-serial'
  // Capture method parameter names in classfiles.
  options.compilerArgs << '-parameters'
}

task enforceVersion {
  def foundVersion = JavaVersion.current();
  if (foundVersion < minJavaVersion) {
    throw new GradleException("Build requires at least Java ${minJavaVersion}; but ${foundVersion}"
        + " was found. Consider setting JAVA_HOME to select a specific JDK on your system.");
  }
}

compileJava.dependsOn(enforceVersion);

task wrapper(type: Wrapper) {
  gradleVersion = project(':buildSrc').GRADLE_VERSION
}

// TODO(ksweeney): Consider pushing this down to API - the scheduler implementation itself should
// only be consumed as an application.
publishing {
  publications {
    mavenJava(MavenPublication) {
      from components.java

      artifactId 'aurora-scheduler'

      artifact sourceJar {
        classifier "sources"
      }
    }
  }
}

task generateBuildProperties (type:Exec) {
  def outputDir = file("${buildDir}/build-properties")
  def outputFile = file("${outputDir}/build.properties")
  outputs.upToDateWhen { false }
  outputs.dir outputDir
  doFirst {
    outputDir.exists() || outputDir.mkdirs()
  }

  commandLine "${projectDir}/build-support/generate-build-properties", "${outputFile}"
}

sourceSets {
  main {
    output.dir generateBuildProperties
    resources {
      srcDir '3rdparty/javascript'
    }
  }
}

dependencies {
  def shiroRev = '1.4.0'
  def jettyDep = '9.3.11.v20160721'

  compile project(':api')
  compile project(':commons')

  compile 'aopalliance:aopalliance:1.0'
  compile "ch.qos.logback:logback-classic:${logbackRev}"
  compile "com.beust:jcommander:1.72"
  compile "com.google.inject:guice:${guiceRev}"
  compile "com.google.inject.extensions:guice-assistedinject:${guiceRev}"
  compile "com.google.inject.extensions:guice-multibindings:${guiceRev}"
  compile "com.google.inject.extensions:guice-servlet:${guiceRev}"
  compile "com.google.protobuf:protobuf-java:${protobufRev}"
  compile 'com.hubspot.jackson:jackson-datatype-protobuf:0.9.3'
  compile "com.fasterxml.jackson.core:jackson-core:${jacksonRev}"
  compile "org.jboss.resteasy:resteasy-guice:${resteasyRev}"
  compile "org.jboss.resteasy:resteasy-jackson-provider:${resteasyRev}"
  compile "org.jboss.resteasy:resteasy-jaxrs:${resteasyRev}"
  compile 'javax.inject:javax.inject:1'
  compile "javax.servlet:javax.servlet-api:${servletRev}"
  compile "org.antlr:stringtemplate:${stringTemplateRev}"
  compile "org.apache.curator:curator-client:${curatorRev}"
  compile "org.apache.curator:curator-framework:${curatorRev}"
  compile "org.apache.curator:curator-recipes:${curatorRev}"
  compile 'org.apache.mesos:mesos:1.6.1'
  compile "org.asynchttpclient:async-http-client:${asyncHttpclientRev}"
  compile "org.apache.shiro:shiro-guice:${shiroRev}"
  compile "org.apache.shiro:shiro-web:${shiroRev}"
  compile "org.apache.zookeeper:zookeeper:${zookeeperRev}"
  compile "org.eclipse.jetty:jetty-rewrite:${jettyDep}"
  compile "org.eclipse.jetty:jetty-server:${jettyDep}"
  compile "org.eclipse.jetty:jetty-servlet:${jettyDep}"
  compile "org.eclipse.jetty:jetty-servlets:${jettyDep}"
  compile 'org.quartz-scheduler:quartz:2.2.2'

  testCompile 'com.sun.jersey:jersey-client:1.19'
  testCompile "junit:junit:${junitRev}"
  testCompile "org.powermock:powermock-module-junit4:1.6.4"
  testCompile "org.powermock:powermock-api-easymock:1.6.4"
}

// For normal developer builds, avoid running the often-time-consuming code quality checks.
// Jenkins will always run these, and developers are encouraged to run these before posting diffs
// and pushing to master.
def runCodeQuality = project.hasProperty('q')
def codeQualityTasks = [
    Checkstyle,
    com.github.spotbugs.SpotBugsTask,
    nl.javadude.gradle.plugins.license.License,
    Pmd
]
codeQualityTasks.each {
  tasks.withType(it) {
    enabled = runCodeQuality
  }
}

checkstyle {
  sourceSets = [sourceSets.main , sourceSets.test, sourceSets.jmh]
  toolVersion = '7.3'
}

spotbugs {
  toolVersion = '3.1.0'
  effort = "max"
}

tasks.withType(com.github.spotbugs.SpotBugsTask) {
  reports {
    xml.enabled = false
    html.enabled = true
  }
  maxHeapSize = '1g'
  excludeFilter = rootProject.file('config/spotbugs/excludeFilter.xml')
}

pmd {
  toolVersion = '5.5.3'
  consoleOutput = true
}

// As recommended here to work around PMD bugs exposed by otherwise
// handing it an `auxClasspath` to resolve types with:
//   https://discuss.gradle.org/t/upgrading-gradle-from-2-7-to-2-8-results-in-pmd-false-positives/13460
tasks.withType(Pmd) {
  classpath = null
}

pmdMain {
  ruleSetFiles = files('config/pmd/common.xml', 'config/pmd/main.xml')
}

pmdTest {
  ruleSetFiles = files('config/pmd/common.xml', 'config/pmd/test.xml')
}

tasks.withType(Test) {
  maxParallelForks = Runtime.runtime.availableProcessors()
}

idea {
  project {
    vcs = 'Git'
    jdkName = '1.8'
    languageLevel = '1.8'

    ipr {
      withXml {
        def projectNode = it.asNode()

        // TODO(wfarner): Does the below work?  It still seems necessary to manually turn on
        // annotation processing.

        // Configure an annotation processor profile.
        def compilerConfiguration = projectNode.find {
          it.name() == 'component' && it.@name == 'CompilerConfiguration'
        }
        def apt = compilerConfiguration.find { it.name() == 'annotationProcessing' }
        // Turn on annotation processing only for the whitelisted modules.
        apt.replaceNode {
          annotationProcessing {
            profile(default: 'true', name: 'Default', enabled: 'false')
            profile(default: 'false', name: 'apt', enabled: 'true') {
              sourceOutputDir(name: 'generated')
              sourceTestOutputDir(name: 'generated')
              processorPath(useClasspath: 'true')
              module(name: 'aurora')
            }
          }
        }
        def projectRoot = projectNode.find {
          it.name() == 'component' && it.@name == 'ProjectRootManager'
        }
        projectRoot.remove(projectRoot.output)
      }
    }
  }
}

// Map output dirs explicitly per-module with the end goal of mapping the annotation processor
// generated code output dirs as source (and test) dirs.  The key difficulty being worked around
// here is the fact that excludes higher in a directory tree override includes deeper in the tree.
allprojects {
  def generatedSourceDir = file("${it.projectDir}/out/production/generated")
  def generatedTestDir = file("${it.projectDir}/out/test/generated")

  idea {
    module {
      generatedSourceDir.exists() || generatedSourceDir.mkdirs()
      sourceDirs += generatedSourceDir
      generatedSourceDirs += generatedSourceDir

      generatedTestDir.exists() || generatedTestDir.mkdirs()
      testSourceDirs += generatedTestDir
      generatedSourceDirs += generatedTestDir

      iml {
        withXml {
          def moduleNode = it.asNode()
          def moduleConfiguration = moduleNode.find {
            it.name() == 'component' && it.@name == 'NewModuleRootManager'
          }
          moduleConfiguration.attributes().remove('inherit-compiler-output')
          moduleConfiguration.appendNode('output', [url: 'file://$MODULE_DIR$/out/production'])
          moduleConfiguration.appendNode('output-test', [url: 'file://$MODULE_DIR$/out/test'])

          def excludeOutput = moduleConfiguration.find { it.name() == 'exclude-output' }
          if (excludeOutput) {
            moduleConfiguration.remove(excludeOutput)
          }
        }
      }
    }
  }
}

// Configuration parameters for the application plugin.
applicationName = 'aurora-scheduler'
mainClassName = 'org.apache.aurora.scheduler.app.SchedulerMain'

// TODO(ksweeney): Configure this to scan resources as well.
tasks.withType(nl.javadude.gradle.plugins.license.License).each {
  it.source = files("$projectDir/src/main/java", "$projectDir/src/test/java")
}

license {
  header rootProject.file('config/checkstyle/apache.header')
  strictCheck true
  skipExistingHeaders true
}

def reportPath = "$buildDir/reports/jacoco/test"
jacocoTestReport {
  group = "Reporting"
  description = "Generate Jacoco coverage reports after running tests."

  sourceDirectories = sourceSets.main.java
  classDirectories = files("$buildDir/classes/main")
  reports {
    xml.enabled true
  }
  doLast {
    println "Coverage report generated: file://$reportPath/html/index.html"
  }
}
test.finalizedBy jacocoTestReport

jacocoTestCoverageVerification {
  violationRules {
    rule {
      limit {
        counter = 'INSTRUCTION'
        minimum = 0.87
      }
    }
    rule {
      limit {
        counter = 'BRANCH'
        minimum = 0.79
      }
    }
  }
}
jacocoTestReport.finalizedBy jacocoTestCoverageVerification

def jmhHumanOutputPath = "$buildDir/reports/jmh/human.txt"
jmh {
  // Run specific benchmarks by passing -Pbenchmarks='<regexp' on the command line.  For example
  // ./gradlew jmh -Pbenchmarks='ThriftApiBenchmarks.*'
  if (project.hasProperty('benchmarks')) {
    include = project.getProperty('benchmarks')
  }
  jmhVersion = '1.15'
  jvmArgsPrepend = '-Xmx3g'
  humanOutputFile = project.file("$jmhHumanOutputPath")
  resultsFile = project.file("$buildDir/reports/jmh/results.txt")
  profilers = ['gc', 'stack']
}
tasks.getByName('jmh').doLast() {
  println "Benchmark report generated: file://$jmhHumanOutputPath"
}

run {
  main = 'org.apache.aurora.scheduler.app.local.LocalSchedulerMain'
  classpath += sourceSets.test.output
}

startScripts {
  def environmentClasspathPrefix = System.env.CLASSPATH_PREFIX

  if (!environmentClasspathPrefix?.trim()) {
    return
  }

  doLast {
    unixScript.text = unixScript.text.replace('CLASSPATH=', "CLASSPATH=${environmentClasspathPrefix}:")
  }
}

// Include a script to run the recovery tool.
task moreStartScripts(type: CreateStartScripts) {
  mainClassName = 'org.apache.aurora.scheduler.storage.durability.RecoveryTool'
  applicationName = 'recovery-tool'
  outputDir = new File(project.buildDir, 'scripts')
  classpath = jar.outputs.files + project.configurations.runtime
}

applicationDistribution.into('bin') {
  from(moreStartScripts)
  fileMode = 0755
}
