/*
 * Licensed to Elasticsearch under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch 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.
 */

esplugin {
  description 'An easy, safe and fast scripting language for Elasticsearch'
  classname 'org.elasticsearch.painless.PainlessPlugin'
}

integTestCluster {
  module project.project(':modules:mapper-extras')
  systemProperty 'es.scripting.update.ctx_in_params', 'false'
}

dependencies {
  compile 'org.antlr:antlr4-runtime:4.5.3'
  compile 'org.ow2.asm:asm-debug-all:5.1'
  compile project('spi')
}

dependencyLicenses {
  mapping from: /asm-.*/, to: 'asm'
}

unitTest {
  jvmArg '-XX:-OmitStackTraceInFastThrow'
}

/* Build Javadoc for the Java classes in Painless's public API that are in the
 * Painless plugin */
task apiJavadoc(type: Javadoc) {
  source = sourceSets.main.allJava
  classpath = sourceSets.main.runtimeClasspath
  include '**/org/elasticsearch/painless/api/'
  destinationDir = new File(docsDir, 'apiJavadoc')
}
task apiJavadocJar(type: Jar) {
  classifier = 'apiJavadoc'
  from apiJavadoc
}
assemble.dependsOn apiJavadocJar

// Reference documentation for Painless's public API.
task generatePainlessApi(type: JavaExec) {
  main = 'org.elasticsearch.painless.PainlessDocGenerator'
  classpath = sourceSets.test.runtimeClasspath
  args file('../../docs/painless/painless-api-reference')
}

/**********************************************
 *            Parser regeneration             *
 **********************************************/

configurations {
  regenerate
}

dependencies {
  regenerate 'org.antlr:antlr4:4.5.3'
}

String grammarPath = 'src/main/antlr'
String outputPath = 'src/main/java/org/elasticsearch/painless/antlr'

task cleanGenerated(type: Delete) {
  delete fileTree(grammarPath) {
    include '*.tokens'
  }
  delete fileTree(outputPath) {
    include 'Painless*.java'
  }
}

task regenLexer(type: JavaExec) {
  dependsOn cleanGenerated
  main = 'org.antlr.v4.Tool'
  classpath = configurations.regenerate
  systemProperty 'file.encoding', 'UTF-8'
  systemProperty 'user.language', 'en'
  systemProperty 'user.country', 'US'
  systemProperty 'user.variant', ''
  args '-Werror',
       '-package', 'org.elasticsearch.painless.antlr',
       '-o', outputPath,
       "${file(grammarPath)}/PainlessLexer.g4"
}

task regenParser(type: JavaExec) {
  dependsOn regenLexer
  main = 'org.antlr.v4.Tool'
  classpath = configurations.regenerate
  systemProperty 'file.encoding', 'UTF-8'
  systemProperty 'user.language', 'en'
  systemProperty 'user.country', 'US'
  systemProperty 'user.variant', ''
  args '-Werror',
       '-package', 'org.elasticsearch.painless.antlr',
       '-no-listener',
       '-visitor',
       // '-Xlog',
       '-o', outputPath,
       "${file(grammarPath)}/PainlessParser.g4"
}

task regen {
  dependsOn regenParser
  doLast {
    // moves token files to grammar directory for use with IDE's
    ant.move(file: "${outputPath}/PainlessLexer.tokens", toDir: grammarPath)
    ant.move(file: "${outputPath}/PainlessParser.tokens", toDir: grammarPath)
    // make the generated classes package private
    ant.replaceregexp(match: 'public ((interface|class) \\QPainless\\E\\w+)',
                      replace: '\\1',
                      encoding: 'UTF-8') {
      fileset(dir: outputPath, includes: 'Painless*.java')
    }
    // make the lexer abstract
    ant.replaceregexp(match: '(class \\QPainless\\ELexer)',
                      replace: 'abstract \\1',
                      encoding: 'UTF-8') {
      fileset(dir: outputPath, includes: 'PainlessLexer.java')
    }
    // nuke timestamps/filenames in generated files
    ant.replaceregexp(match: '\\Q// Generated from \\E.*',
                      replace: '\\/\\/ ANTLR GENERATED CODE: DO NOT EDIT',
                      encoding: 'UTF-8') {
      fileset(dir: outputPath, includes: 'Painless*.java')
    }
    // remove tabs in antlr generated files
    ant.replaceregexp(match: '\t', flags: 'g', replace: '  ', encoding: 'UTF-8') {
      fileset(dir: outputPath, includes: 'Painless*.java')
    }
    // fix line endings
    ant.fixcrlf(srcdir: outputPath, eol: 'lf') {
      patternset(includes: 'Painless*.java')
    }
  }
}