/*
 * 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.
 */
import org.apache.aurora.build.CoverageReportCheck
import org.gradle.api.JavaVersion

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 'me.champeau.gradle.jmh' version '0.2.0'
}

apply plugin: 'application'
apply plugin: 'checkstyle'
apply plugin: 'findbugs'
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.11.1'
  ext.gsonRev = '2.3.1'
  ext.guavaRev = '20.0'
  ext.guiceRev = '3.0'
  ext.httpclientRev = '4.5.2'
  ext.httpcoreRev = '4.4.4'
  ext.jacksonRev = '2.5.1'
  ext.jerseyRev = '1.19'
  ext.jsrRev = '3.0.1'
  ext.junitRev = '4.12'
  ext.logbackRev = '1.2.3'
  ext.mybatisRev = '3.4.1'
  ext.protobufRev = '2.6.1'
  ext.servletRev = '3.1.0'
  ext.slf4jRev = '1.7.25'
  ext.stringTemplateRev = '3.2.1'
  ext.thriftRev = '0.9.1'
  ext.zookeeperRev = '3.4.8'

  configurations {
    compile {
      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 "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 "junit:junit:${junitRev}"
        force "org.apache.thrift:libthrift:${thriftRev}"
        force "org.apache.zookeeper:zookeeper:${zookeeperRev}"
        force "org.hamcrest:hamcrest-core:1.3"
        force "org.slf4j:slf4j-api:${slf4jRev}"
        force "org.mybatis:mybatis:${mybatisRev}"
      }
    }
  }
}

/* This gradle project contains the annotation procesor from
 * com.twitter.common.args and related dependencies. It needs to be outside of
 * the commons project because gradle needs to compile the annotation processor
 * first.
 */
project(':commons-args') {
  dependencies {
    compile "com.google.guava:guava:${guavaRev}"
    compile "com.google.code.findbugs:jsr305:${jsrRev}"
    compile "commons-lang:commons-lang:${commonsLangRev}"
  }

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

project(':commons') {
  apply plugin: org.apache.aurora.build.ThriftPlugin
  thrift {
    version = thriftRev
  }

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

  dependencies {
    compile project(':commons-args')

    compile "com.google.code.findbugs:jsr305:${jsrRev}"
    compile "com.google.code.gson:gson:${gsonRev}"
    compile "com.google.guava:guava:${guavaRev}"
    compile "com.google.inject.extensions:guice-multibindings:${guiceRev}"
    compile "com.google.inject:guice:${guiceRev}"
    compile "com.sun.jersey:jersey-core:${jerseyRev}"
    compile "commons-lang:commons-lang:${commonsLangRev}"
    compile "javax.servlet:javax.servlet-api:${servletRev}"
    compile "joda-time:joda-time:2.9.1"
    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}"
    testCompile "org.powermock:powermock-module-junit4:1.6.4"
    testCompile "org.powermock:powermock-api-easymock:1.6.4"
  }
}

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

  task checkPython << {
    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.2.5'
  def jettyDep = '9.3.11.v20160721'

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

  compile 'aopalliance:aopalliance:1.0'
  compile "ch.qos.logback:logback-classic:${logbackRev}"
  compile "com.google.code.findbugs:jsr305:${jsrRev}"
  compile "com.google.inject:guice:${guiceRev}"
  compile "com.google.inject.extensions:guice-assistedinject:${guiceRev}"
  compile "com.google.protobuf:protobuf-java:${protobufRev}"
  compile 'com.h2database:h2:1.4.193'
  compile 'com.hubspot.jackson:jackson-datatype-protobuf:0.9.3'
  compile "com.fasterxml.jackson.core:jackson-core:${jacksonRev}"
  compile "com.sun.jersey:jersey-core:${jerseyRev}"
  compile "com.sun.jersey:jersey-json:${jerseyRev}"
  compile "com.sun.jersey:jersey-server:${jerseyRev}"
  compile "com.sun.jersey:jersey-servlet:${jerseyRev}"
  compile "com.sun.jersey.contribs:jersey-guice:${jerseyRev}"
  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.2.0'
  compile "org.apache.httpcomponents:httpclient:${httpclientRev}"
  compile "org.apache.httpcomponents:httpcore:${httpcoreRev}"
  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.mybatis:mybatis:${mybatisRev}"
  compile 'org.mybatis:mybatis-guice:3.7'
  compile 'org.mybatis:mybatis-migrations:3.2.0'
  compile 'org.quartz-scheduler:quartz:2.2.2'
  compile "uno.perk:forward:1.0.0"

  testCompile "com.sun.jersey:jersey-client:${jerseyRev}"
  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,
    FindBugs,
    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'
}

findbugs {
  toolVersion = '3.0.1'
  effort = "max"
}

tasks.withType(FindBugs) {
  reports {
    xml.enabled = false
    html.enabled = true
  }
  maxHeapSize = '2g'
  excludeFilter = rootProject.file('config/findbugs/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')
}

/**
 * There is a jshint target recommended in the README for gradle-js-plugin
 * but it does not work. This workaround from here:
 * https://github.com/eriwen/gradle-js-plugin/issues/73
 */
task jsHint(type:com.eriwen.gradle.js.tasks.JsHintTask) {
  source = fileTree("src/main/resources/$httpAssetsPath/js/")
  dest file("${buildDir}/jshint.out")
  // Set this to false once JS code complies with JSHint.
  ignoreExitCode false
  outputToStdOut true
  jshint.options = [
    // See: http://www.jshint.com/docs/options/ for explanation.
    browser: true,
    camelcase: true,
    curly: true,
    eqeqeq: true,
    indent: 2,
    maxlen: 100,
    quotmark: true,
    trailing: true,
    undef: true,
    unused: 'vars',
    white: true
  ]
  jshint.predef = [
    '_': true,
    'angular': true,
    'moment': true,
    'Thrift': true
  ]
}
tasks.checkstyleMain.dependsOn(jsHint)

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

// Turn on annotation processors for commons (uses commons-args) and aurora
// (uses commons-args, forward, ...).  The crux here is _not_ turning annotation processing on
// for commons-args (this leads to an attempt at self-processing before its processor is
// compiled); so the strategy taken is to white-list modules.
//
// NB: Unfortunately, most of the ipr/iml modeling we need is not exposed by the idea plugin DSL so
// we drop to xml manipulation here only out of necessity.
def apt_projects = ['commons', 'aurora']

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

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

        // 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')
              apt_projects.each {
                module(name: it)
              }
            }
          }
        }
        def projectRoot = projectNode.find {
          it.name() == 'component' && it.@name == 'ProjectRootManager'
        }
        projectRoot.remove(projectRoot.output)

        // Add parameter names to generated class file debug info.
        projectNode
            .appendNode('component', [name: 'JavacSettings'])
            .appendNode('option', [name: 'ADDITIONAL_OPTIONS_STRING', value: '-parameters'])
      }
    }
  }
}

// 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 isApt = it.name in apt_projects
  def generatedSourceDir = file("${it.projectDir}/out/production/generated")
  def generatedTestDir = file("${it.projectDir}/out/test/generated")

  idea {
    module {
      if (isApt) {
        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'])

          if (isApt) {
            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

task analyzeReport(type: CoverageReportCheck) {
  coverageReportFile = "$reportPath/jacocoTestReport.xml"
  minInstructionCoverage = 0.89
  minBranchCoverage = 0.835
  legacyClassesWithoutCoverage = file('config/legacy_untested_classes.txt').readLines()
}
jacocoTestReport.finalizedBy analyzeReport

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")
}
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}:")
  }
}
