/*
 * 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.0"
}

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.5.0'
  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
}
