import java.nio.charset.Charset
import java.util.function.Function

/*
 * 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.
 */

// This adds javacc generation support.

configure(rootProject) {
  configurations {
    javacc
  }

  dependencies {
    javacc "net.java.dev.javacc:javacc:${scriptDepVersions['javacc']}"
  }

  task javacc() {
    description "Regenerate sources for corresponding javacc grammar files."
    group "generation"

    dependsOn allprojects.collect { prj -> prj.tasks.withType(JavaCCTask) }
  }
}

/**
 * Utility function to read a file, apply changes to its content and write it back.
 */
def modifyFile = { File path, Function<String, String> modify ->
  Function<String, String> normalizeEols = { text -> text.replace("\r\n", "\n") }
  modify = normalizeEols.andThen(modify).andThen(normalizeEols)

  String original = path.getText("UTF-8")
  String modified = modify.apply(original)
  if (!original.equals(modified)) {
    path.write(modified, "UTF-8")
  }
}

def commonCleanups = { FileTree generatedFiles ->
  // This is a minor typo in a comment that nonetheless people have hand-corrected in the past.
  generatedFiles.matching({ include "CharStream.java" }).each {file ->
    modifyFile(file, { text ->
      return text.replace(
          "implemetation",
          "implementation");
    })
  }

  generatedFiles.each {file ->
    modifyFile(file, { text ->
      // Normalize EOLs and tabs (EOLs are a side-effect of modifyFile).
      text = text.replace("\t", "    ");
      text = text.replaceAll("JavaCC - OriginalChecksum=[^*]+", "(filtered)")
      text = text.replace("StringBuffer", "StringBuilder")
      return text
    })
  }

  generatedFiles.matching({ include "*TokenManager.java" }).each { file ->
    modifyFile(file, { text ->
      // Remove redundant imports.
      text = text.replaceAll(
          /(?m)^import .+/,
          "")
      // Add CharStream imports.
      text = text.replaceAll(
          /package (.+)/,
          '''
          package $1
          import org.apache.lucene.queryparser.charstream.CharStream; 
          '''.trim())
      // Eliminates redundant cast message.
      text = text.replace(
          "int hiByte = (int)(curChar >> 8);",
          "int hiByte = curChar >> 8;")
      // Access to forbidden APIs.
      text = text.replace(
          "public  java.io.PrintStream debugStream = System.out;",
          "// (debugStream omitted).")
      text = text.replace(
          "public  void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }",
          "// (setDebugStream omitted).")
      return text
    })
  }
}

configure(project(":lucene:queryparser")) {
  task javaccParserClassic(type: JavaCCTask) {
    description "Regenerate classic query parser from lucene/queryparser/classic/QueryParser.jj"
    group "generation"

    javaccFile = file('src/java/org/apache/lucene/queryparser/classic/QueryParser.jj')

    afterGenerate << commonCleanups
    afterGenerate << { FileTree generatedFiles ->
      generatedFiles.matching { include "QueryParser.java" }.each { file ->
        modifyFile(file, { text ->
          text = text.replace(
              "public QueryParser(CharStream ",
              "protected QueryParser(CharStream ")
          text = text.replace(
              "public QueryParser(QueryParserTokenManager ",
              "protected QueryParser(QueryParserTokenManager ")
          text = text.replace(
              "new java.util.ArrayList<int[]>",
              "new java.util.ArrayList<>")
          return text
        })
      }
    }
  }

  task javaccParserSurround(type: JavaCCTask) {
    description "Regenerate surround query parser from lucene/queryparser/surround/parser/QueryParser.jj"
    group "generation"

    javaccFile = file('src/java/org/apache/lucene/queryparser/surround/parser/QueryParser.jj')

    afterGenerate << commonCleanups
    afterGenerate << { FileTree generatedFiles ->
      generatedFiles.matching { include "QueryParser.java" }.each { file ->
        modifyFile(file, { text ->
          text = text.replace(
              "import org.apache.lucene.analysis.TokenStream;",
              "")
          text = text.replace(
              "new java.util.ArrayList<int[]>",
              "new java.util.ArrayList<>")
          return text
        })
      }
    }
  }

  task javaccParserFlexible(type: JavaCCTask) {
    description "Regenerate Flexible query parser from queryparser/flexible/standard/parser/StandardSyntaxParser.jj"
    group "generation"

    javaccFile = file('src/java/org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParser.jj')

    afterGenerate << commonCleanups
    afterGenerate << { FileTree generatedFiles ->
      generatedFiles.matching { include "ParseException.java" }.each { file ->
        modifyFile(file, { text ->
          // Modify constructor.
          text = text.replace(
              "class ParseException extends Exception",
              "class ParseException extends QueryNodeParseException")

          // Modify imports.
          text = text.replace(
              "package org.apache.lucene.queryparser.flexible.standard.parser;", '''\
          package org.apache.lucene.queryparser.flexible.standard.parser;

          import org.apache.lucene.queryparser.flexible.messages.*;
          import org.apache.lucene.queryparser.flexible.core.*;
          import org.apache.lucene.queryparser.flexible.core.messages.*;
          ''')

          // Modify constructors and code bits
          text = text.replaceAll(
              /(?s)[ ]*public ParseException\(Token currentTokenVal[^}]+[}]/, '''\
          public ParseException(Token currentTokenVal,
            int[][] expectedTokenSequencesVal, String[] tokenImageVal) 
          {
            super(new MessageImpl(QueryParserMessages.INVALID_SYNTAX, initialise(
            currentTokenVal, expectedTokenSequencesVal, tokenImageVal)));
            this.currentToken = currentTokenVal;
            this.expectedTokenSequences = expectedTokenSequencesVal;
            this.tokenImage = tokenImageVal;
          }
          ''')

          text = text.replaceAll(
              /(?s)[ ]*public ParseException\(String message\)[^}]+[}]/, '''\
          public ParseException(Message message) 
          {
            super(message);
          }
          ''')

          text = text.replaceAll(
              /(?s)[ ]*public ParseException\(\)[^}]+[}]/, '''\
          public ParseException() 
          {
            super(new MessageImpl(QueryParserMessages.INVALID_SYNTAX, "Error"));
          }
          ''')
          return text
        })
      }

      generatedFiles.matching { include "StandardSyntaxParser.java" }.each { file ->
        modifyFile(file, { text ->
          // Remove redundant cast
          text = text.replace(
              "new java.util.ArrayList<int[]>",
              "new java.util.ArrayList<>")
          text = text.replace(
              "new ArrayList<QueryNode>()",
              "new ArrayList<>()")
          text = text.replace(
              "Collections.<QueryNode> singletonList",
              "Collections.singletonList")
          return text
        })
      }
    }
  }

  task javacc() {
    description "Regenerate query parsers (javacc syntax definitions)."
    group "generation"

    dependsOn javaccParserClassic
    dependsOn javaccParserSurround
    dependsOn javaccParserFlexible
  }
}

configure(project(":solr:core")) {
  task javacc(type: JavaCCTask) {
    description "Regenerate Solr query parser"
    group "generation"

    javaccFile = file('src/java/org/apache/solr/parser/QueryParser.jj')


    afterGenerate << commonCleanups
    afterGenerate << { FileTree generatedFiles ->
      generatedFiles.matching { include "QueryParser.java" }.each { file ->
        modifyFile(file, { text ->
          text = text.replace(
              "public QueryParser(CharStream ",
              "protected QueryParser(CharStream ")
          text = text.replace(
              "public QueryParser(QueryParserTokenManager ",
              "protected QueryParser(QueryParserTokenManager ")
          text = text.replace(
              "final private LookaheadSuccess jj_ls =",
              "static final private LookaheadSuccess jj_ls =")
          return text
        })
      }
    }
  }
}



// We always regenerate, no need to declare outputs.
class JavaCCTask extends DefaultTask {
  @Input
  File javaccFile

  /**
   * Apply closures to all generated files before they're copied back
   * to mainline code.
   */
  @Optional
  @Input
  List<Closure<FileTree>> afterGenerate = new ArrayList<>()

  JavaCCTask() {
    dependsOn(project.rootProject.configurations.javacc)
  }

  @TaskAction
  def generate() {
    if (!javaccFile || !javaccFile.exists()) {
      throw new GradleException("Input file does not exist: ${javaccFile}")
    }

    // Run javacc generation into temporary folder so that we know all the generated files
    // and can post-process them easily.
    def tempDir = this.getTemporaryDir()
    tempDir.mkdirs()
    project.delete project.fileTree(tempDir, { include: "**/*.java" })

    def targetDir = javaccFile.parentFile
    logger.lifecycle("Regenerating JavaCC:\n  from: ${javaccFile}\n    to: ${targetDir}")

    def output = new ByteArrayOutputStream()
    def result = project.javaexec {
      classpath {
        project.rootProject.configurations.javacc
      }

      ignoreExitValue = true
      standardOutput = output
      errorOutput = output

      main = "org.javacc.parser.Main"
      args += [
          "-OUTPUT_DIRECTORY=${tempDir}",
          javaccFile
      ]
    }

    // Unless we request verbose logging, don't emit javacc output.
    if (result.exitValue != 0) {
      throw new GradleException("JavaCC failed to compile ${javaccFile}, here is the compilation output:\n${output}")
    }

    // Make sure we don't have warnings.
    if (output.toString(Charset.defaultCharset()).contains("Warning:")) {
      throw new GradleException("JavaCC emitted warnings for ${javaccFile}, here is the compilation output:\n${output}")
    }

    // Apply any custom modifications.
    def generatedFiles = project.fileTree(tempDir)

    afterGenerate.each {closure ->
      closure.call(generatedFiles)
    }

    // Copy back to mainline sources.
    project.copy {
      from tempDir
      into targetDir

      // We don't need CharStream interface as we redirect to our own.
      exclude "CharStream.java"
    }
  }
}
