/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

buildscript {
  repositories {
      mavenCentral()
  }

  // autojar only works with gradle versions < 4.0
  // we need to fix it or find a different solution in order to upgrade gradle
  dependencies {
      classpath 'com.github.rholder:gradle-autojar:1.0.1'
  }
}

plugins {
    id "de.undercouch.download" version "3.3.0"
}

apply plugin: 'java'
apply plugin: 'gradle-autojar'

// append "-incubating" while still in the incubating process
archivesBaseName = 'datafu-pig-incubating'

import groovy.xml.MarkupBuilder

// the autojarred configuration includes all JARs that will be included
// in the final JAR via autojar
configurations.create('autojarred')

configurations.create('jarjar')

configurations {
  compile {
    extendsFrom autojarred
  }
}

eclipse {
  jdt {
    file {
      withProperties {  properties ->
        // set up annotation processing, which we use so we can have multi-line strings in our tests
        properties.setProperty("org.eclipse.jdt.core.compiler.processAnnotations", "enabled")
      }
    }
  }
}

// need to assemble the build plugin for eclipse since tests use the annotation processor defined there
tasks.eclipse.dependsOn(':build-plugin:assemble')

// more annotation processor setup
eclipseJdt {
  doFirst {
    def f = file(".factorypath")
    def w = new FileWriter(f)
    def xml = new MarkupBuilder(w)
    xml.setDoubleQuotes(true)
    xml."factorypath"() {
      "factorypathentry" (
        kind: "EXTJAR",
        id: configurations.testCompile.find {
          it.name.startsWith("build-plugin")
        },
        enabled: true,
        runInBatchMode: false
      )
    }
    w.close()
  }
}

cleanEclipse {
  doLast {
    delete ".apt_generated"
    delete ".settings"
    delete ".factorypath"
    delete "bin"
  }
}

jar
{
  // initial jar only includes the main classes of datafu, not the dependencies.
  // this is not the one we'll publish.
  classifier = "core"
}

ext
{
  autojarBuildDir = tasks.jar.destinationDir
}

task jarWithDependencies(type: Autojar) {
  description 'Creates a jar that includes the dependencies (under their own namespaces)'
  autojarFiles = [
    tasks.jar.getArchivePath().absoluteFile,
    "META-INF/LICENSE",
    "META-INF/DISCLAIMER",
    "META-INF/NOTICE"
  ]
  targetConfiguration = configurations.autojarred
  autojarExtra = '-baeq'
}

def outputFile = file(tasks.jar.getArchivePath().absoluteFile.toString().replace("-core","-jarjar"))

task jarWithDependenciesNamespaced(dependsOn: jarWithDependencies) {
  description 'Creates the jar that includes dependencies (under a datafu namespace)'

  doLast {
    project.ant {
      taskdef name: "jarjar", classname: "com.tonicsystems.jarjar.JarJarTask", classpath: configurations.jarjar.asPath
      jarjar(jarfile: outputFile, filesetmanifest: "merge") {
        zipfileset(src: tasks.jarWithDependencies.autojarOutput)
        rule pattern: "it.unimi.dsi.fastutil.**", result: "datafu.it.unimi.dsi.fastutil.@1"
        rule pattern: "org.apache.commons.math.**", result: "datafu.org.apache.commons.math.@1"
        rule pattern: "com.clearspring.analytics.**", result: "datafu.com.clearspring.analytics.@1"
        rule pattern: "com.google.common.**", result: "datafu.com.google.common.@1"
        rule pattern: "opennlp.**", result: "datafu.opennlp.@1"
      }
    }
  }
}

task finalJar(type: Jar, dependsOn: jarWithDependenciesNamespaced) {
  description 'Creates the final jar'

  from(zipTree(outputFile))
}

// don't publish the core archive, as this doesn't have the dependencies
configurations.archives.artifacts.removeAll { return it.classifier == "core"; }

artifacts {
  archives finalJar
}

dependencies {
  // dependencies that are packaged into the jar using autojar
  // autojar only includes what is needed
  autojarred "it.unimi.dsi:fastutil:$fastutilVersion"
  autojarred "org.apache.commons:commons-math:$commonsMathVersion"
  autojarred "com.clearspring.analytics:stream:$streamVersion"
  autojarred "com.google.guava:guava:$guavaVersion"
  autojarred "org.apache.opennlp:opennlp-tools:$openNlpVersion"
  autojarred "org.apache.opennlp:opennlp-uima:$openNlpVersion"
  autojarred "org.apache.opennlp:opennlp-maxent:$openNlpMaxEntVersion"

  // needed to run jarjar
  jarjar "com.googlecode.jarjar:jarjar:1.3"

  // not included in autojar because it's already a pig dependency and so
  // should be available
  compile "joda-time:joda-time:$jodaTimeVersion"

  testCompile "org.apache.pig:pigunit:$pigVersion"
  testCompile "log4j:log4j:$log4jVersion"
  testCompile "jline:jline:$jlineVersion"
  testCompile "org.antlr:antlr:$antlrVersion"
  testCompile "commons-io:commons-io:$commonsIoVersion"

  testCompile "org.testng:testng:$testngVersion"
  testCompile project(":build-plugin")
}

modifyPom {
  project {
    dependencies {
      // No dependencies because everything we need is autojarred.
      // The only exception is joda-time, but this is already a pig dependency
      // so it should already be available.
    }
  }
}

if (hadoopVersion.startsWith("2.") || hadoopVersion.startsWith("0.23.")) {
  dependencies {
    // needed for compilation only.  obviously don't need to autojar this.
    compile "org.apache.pig:pig:$pigVersion:h2"
    compile "org.apache.hadoop:hadoop-common:$hadoopVersion"
    compile "org.apache.hadoop:hadoop-hdfs:$hadoopVersion"
    compile "org.apache.hadoop:hadoop-mapreduce-client-jobclient:$hadoopVersion"
  }
} else {
  dependencies {
    // needed for compilation only.  obviously don't need to autojar this.
    compile "org.apache.pig:pig:$pigVersion"
    compile "org.apache.hadoop:hadoop-core:$hadoopVersion"
  }
}

compileTestJava.doFirst {
  options.compilerArgs = ['-processor', 'org.adrianwalker.multilinestring.MultilineProcessor']
}

// open NLP models used for testing.  these are not shipped with datafu.
task downloadOpenNlpModels << {
  download {
    src 'http://opennlp.sourceforge.net/models-1.5/en-pos-maxent.bin'
    dest file('data/en-pos-maxent.bin')
    onlyIfNewer true
  }
  download {
    src 'http://opennlp.sourceforge.net/models-1.5/en-sent.bin'
    dest file('data/en-sent.bin')
    onlyIfNewer true
  }
  download {
    src 'http://opennlp.sourceforge.net/models-1.5/en-token.bin'
    dest file('data/en-token.bin')
    onlyIfNewer true
  }
}

// download models so can test in eclipse or testng
tasks.eclipse.dependsOn('downloadOpenNlpModels')
tasks.test.dependsOn('downloadOpenNlpModels')

test {
  // enable TestNG support (default is JUnit)
  useTestNG()

  systemProperty 'datafu.jar.dir', file('build/libs')
  systemProperty 'datafu.data.dir', file('data')

  maxHeapSize = "2G"
}
