import javax.annotation.Nullable

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

// generate javadocs by calling javadoc tool
// see https://docs.oracle.com/en/java/javase/11/tools/javadoc.html

def resources = scriptResources(buildscript)

allprojects {
  plugins.withType(JavaPlugin) {
    configurations {
      missingdoclet
    }

    dependencies {
      missingdoclet "org.apache.lucene.tools:missing-doclet"
    }

    ext {
      relativeDocPath = project.path.replaceFirst(/:\w+:/, "").replace(':', '/')
    }

    // We disable the default javadoc task and have our own
    // javadoc rendering task below. The default javadoc task
    // will just invoke 'renderJavadoc' (to allow people to call
    // conventional task name).
    tasks.matching { it.name == "javadoc" }.all {
      enabled = false
      dependsOn "renderJavadoc"
    }

    task renderJavadoc(type: RenderJavadocTask) {
      description "Generates Javadoc API documentation for the main source code. This directly invokes javadoc tool."
      group "documentation"

      taskResources = resources
      dependsOn sourceSets.main.compileClasspath
      classpath = sourceSets.main.compileClasspath
      srcDirSet = sourceSets.main.java

      outputDir = project.javadoc.destinationDir
    }

    task renderSiteJavadoc(type: RenderJavadocTask) {
      description "Generates Javadoc API documentation for the site (relative links)."
      group "documentation"

      taskResources = resources
      dependsOn sourceSets.main.compileClasspath
      classpath = sourceSets.main.compileClasspath;
      srcDirSet = sourceSets.main.java;

      relativeProjectLinks = true

      // Place the documentation under Lucene or Solr's documentation directory.
      // docroot is defined in 'documentation.gradle'
      outputDir = project.docroot.toPath().resolve(project.relativeDocPath).toFile()
    }
  }
}

// Set up titles and link up some offline docs for all documentation
// (they may be unused but this doesn't do any harm).

def javaJavadocPackages = rootProject.file("${resources}/java11/")
def junitJavadocPackages = rootProject.file("${resources}/junit/")
allprojects {
  project.tasks.withType(RenderJavadocTask) {
    title = "${project.path.startsWith(':lucene') ? 'Lucene' : 'Solr'} ${project.version} ${project.name} API"

    offlineLinks += [
        "https://docs.oracle.com/en/java/javase/11/docs/api/": javaJavadocPackages,
        "https://junit.org/junit4/javadoc/4.12/": junitJavadocPackages
    ]

    // Set up custom doclet.
    dependsOn configurations.missingdoclet
    docletpath = configurations.missingdoclet
  }
}

// Configure project-specific tweaks and to-dos.

configure(project(":lucene:analysis:common")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "class"
  }
}

configure([
    project(":lucene:analysis:kuromoji"),
    project(":lucene:analysis:nori"),
    project(":lucene:analysis:opennlp"),
    project(":lucene:analysis:smartcn"),
    project(":lucene:benchmark"),
    project(":lucene:codecs"),
    project(":lucene:grouping"),
    project(":lucene:highlighter"),
    project(":lucene:luke"),
    project(":lucene:monitor"),
    project(":lucene:queries"),
    project(":lucene:queryparser"),
    project(":lucene:replicator"),
    project(":lucene:spatial-extras"),
  ]) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "class"
  }
}

configure([
    project(":lucene:analysis:icu"),
    project(":lucene:analysis:morfologik"),
    project(":lucene:analysis:phonetic"),
    project(":lucene:analysis:stempel"),
    project(":lucene:classification"),
    project(":lucene:demo"),
    project(":lucene:expressions"),
    project(":lucene:facet"),
    project(":lucene:join"),
    project(":lucene:spatial3d"),
    project(":lucene:suggest"),
  ]) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing @param tags
    javadocMissingLevel = "method"
  }
}

configure(project(":lucene:backward-codecs")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing @param tags
    javadocMissingLevel = "method"
  }
}

configure(project(":lucene:test-framework")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "class"
    // TODO: clean up split packages
    javadocMissingIgnore = [
        "org.apache.lucene.analysis",
        "org.apache.lucene.analysis.standard",
        "org.apache.lucene.codecs",
        "org.apache.lucene.codecs.blockterms",
        "org.apache.lucene.codecs.bloom",
        "org.apache.lucene.codecs.compressing",
        "org.apache.lucene.codecs.uniformsplit",
        "org.apache.lucene.codecs.uniformsplit.sharedterms",
        "org.apache.lucene.geo",
        "org.apache.lucene.index",
        "org.apache.lucene.search",
        "org.apache.lucene.search.similarities",
        "org.apache.lucene.search.spans",
        "org.apache.lucene.store",
        "org.apache.lucene.util",
        "org.apache.lucene.util.automaton",
        "org.apache.lucene.util.fst"
    ]
  }
}

configure(project(":lucene:sandbox")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "class"
  }
}

configure(project(":lucene:misc")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "class"
  }
}

configure(project(":lucene:core")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "class"
    // some packages are fixed already
    javadocMissingMethod = [
        "org.apache.lucene.util.automaton",
        "org.apache.lucene.analysis.standard",
        "org.apache.lucene.analysis.tokenattributes",
        "org.apache.lucene.document",
        "org.apache.lucene.search.similarities",
        "org.apache.lucene.index",
        "org.apache.lucene.codecs",
        "org.apache.lucene.codecs.lucene50",
        "org.apache.lucene.codecs.lucene60",
        "org.apache.lucene.codecs.lucene80",
        "org.apache.lucene.codecs.lucene84",
        "org.apache.lucene.codecs.lucene86",
        "org.apache.lucene.codecs.lucene87",
        "org.apache.lucene.codecs.perfield"
    ]
  }
}

configure(project(":solr").allprojects) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: fix missing javadocs
    javadocMissingLevel = "package"
  }
}

configure(project(":solr:contrib:analysis-extras")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: clean up split packages
    javadocMissingIgnore = [
        "org.apache.solr.schema",
        "org.apache.solr.update.processor"
    ]
  }
}

configure(project(":solr:contrib:analytics")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: clean up split packages
    javadocMissingIgnore = [
        "org.apache.solr.handler",
        "org.apache.solr.handler.component",
        "org.apache.solr.response"
    ]
  }
}

configure(project(":solr:contrib:langid")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: clean up split packages
    javadocMissingIgnore = [ "org.apache.solr.update.processor" ]
  }
}

configure(project(":solr:solrj")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: clean up split packages
    javadocMissingIgnore = [ "org.apache.solr.client.solrj.embedded" ]
  }
}

configure(project(":solr:test-framework")) {
  project.tasks.withType(RenderJavadocTask) {
    // TODO: clean up split packages
    javadocMissingIgnore = [
        "org.apache.solr",
        "org.apache.solr.analysis",
        "org.apache.solr.cloud",
        "org.apache.solr.core",
        "org.apache.solr.handler.component",
        "org.apache.solr.update.processor",
        "org.apache.solr.util"
    ]
  }
}

// Fix for Java 11 Javadoc tool that cannot handle split packages between modules correctly.
// (by removing all the packages which are part of lucene-core)
// See: https://issues.apache.org/jira/browse/LUCENE-8738?focusedCommentId=16818106&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16818106
// LUCENE-9499: This workaround should be applied only to test-framework (we have no split package in other modules).
configure(project(":lucene:test-framework")) {
  project.tasks.withType(RenderJavadocTask) {
    doLast {
      Set luceneCorePackages = file("${project(':lucene:core').tasks[name].outputDir}/element-list").readLines('UTF-8').toSet();
      File elementFile = file("${outputDir}/element-list");
      List elements = elementFile.readLines('UTF-8');
      elements.removeAll(luceneCorePackages)
      elementFile.write(elements.join('\n').concat('\n'), 'UTF-8');
    }
  }
}

configure(project(':lucene:demo')) {
  project.tasks.withType(RenderJavadocTask) {
    // For the demo, we link the example source in the javadocs, as it's ref'ed elsewhere
    linksource = true
  }
}

// Disable Javadoc rendering for these projects.
configure(subprojects.findAll { it.path in [
    ':solr:solr-ref-guide',
    ':solr:server',
    ':solr:webapp']}) {
  project.tasks.withType(RenderJavadocTask) {
    enabled = false
  }
}

// Add cross-project documentation task dependencies:
// - each RenderJavaDocs task gets a dependency to all tasks with same name in its dependencies
// - the dependency is using dependsOn with a closure to enable lazy evaluation
configure(subprojects) {
  project.tasks.withType(RenderJavadocTask) { task ->
    task.dependsOn {
      task.project.configurations.implementation.allDependencies.withType(ProjectDependency).collect { dep ->
        def otherProject = dep.dependencyProject
        return otherProject.tasks.findByName(task.name)
      }
    }
  }
}

class RenderJavadocTask extends DefaultTask {
  @InputFiles
  @SkipWhenEmpty
  SourceDirectorySet srcDirSet;
  
  @OutputDirectory
  File outputDir

  @CompileClasspath
  FileCollection classpath

  @CompileClasspath
  FileCollection docletpath

  @Input
  String title

  @Input
  boolean linksource = false

  @Input
  boolean relativeProjectLinks = false

  @Input
  def offlineLinks = [:]

  @Input
  def luceneDocUrl = "${->project.luceneDocUrl}"

  @Input
  def solrDocUrl = "${->project.solrDocUrl}"

  // default is to require full javadocs
  @Input
  String javadocMissingLevel = "parameter"

  // anything in these packages is checked with level=method. This allows iteratively fixing one package at a time.
  @Input
  List<String> javadocMissingMethod = []

  // default is not to ignore any elements, should only be used to workaround split packages
  @Input
  List<String> javadocMissingIgnore = []


  @Nullable
  @Optional
  @Input
  def executable

  @Input
  def taskResources

  /** Utility method to recursively collect all tasks with same name like this one that we depend on */
  private Set findRenderTasksInDependencies() {
    Set found = []
    def collectDeps
    collectDeps = { task -> task.taskDependencies.getDependencies(task).findAll{ it.name == this.name && it.enabled && !found.contains(it) }.each{
      found << it
      collectDeps(it)
    }}
    collectDeps(this)
    return found
  }

  @TaskAction
  public void render() {
    def srcDirs = srcDirSet.srcDirs.findAll { dir -> dir.exists() }
    def optionsFile = project.file("${getTemporaryDir()}/javadoc-options.txt")
    
    // create the directory, so relative link calculation knows that it's a directory:
    outputDir.mkdirs();
    
    def opts = []
    opts << [ '-overview', project.file("${srcDirs[0]}/overview.html") ]
    opts << [ '-sourcepath', srcDirs.join(File.pathSeparator) ]
    opts << [ '-subpackages', project.path.startsWith(':lucene') ? 'org.apache.lucene' : 'org.apache.solr' ]
    opts << [ '-d', outputDir ]
    opts << '-protected'
    opts << [ '-encoding', 'UTF-8' ]
    opts << [ '-charset', 'UTF-8' ]
    opts << [ '-docencoding', 'UTF-8' ]
    opts << '-noindex'
    opts << '-author'
    opts << '-version'
    if (linksource) {
      opts << '-linksource'
    }
    opts << '-use'
    opts << [ '-locale', 'en_US' ]
    opts << [ '-windowtitle', title ]
    opts << [ '-doctitle', title ]
    if (!classpath.isEmpty()) {
      opts << [ '-classpath', classpath.asPath ]
    }
    opts << [ '-bottom', "<i>Copyright &copy; 2000-${project.buildYear} Apache Software Foundation. All Rights Reserved.</i>" ]

    opts << [ '-tag', 'lucene.experimental:a:WARNING: This API is experimental and might change in incompatible ways in the next release.' ]
    opts << [ '-tag', 'lucene.internal:a:NOTE: This API is for internal purposes only and might change in incompatible ways in the next release.' ]
    opts << [ '-tag', "lucene.spi:t:SPI Name (case-insensitive: if the name is 'htmlStrip', 'htmlstrip' can be used when looking up the service)." ]

    opts << [ '-doclet', "org.apache.lucene.missingdoclet.MissingDoclet" ]
    opts << [ '-docletpath', docletpath.asPath ]
    opts << [ '--missing-level', javadocMissingLevel ]
    if (javadocMissingIgnore) {
      opts << [ '--missing-ignore', String.join(',', javadocMissingIgnore) ]
    }
    if (javadocMissingMethod) {
      opts << [ '--missing-method', String.join(',', javadocMissingMethod) ]
    }

    opts << [ '-quiet' ]

    def allOfflineLinks = [:]
    allOfflineLinks.putAll(offlineLinks)

    // Resolve inter-project links:
    // - find all (enabled) tasks this tasks depends on (with same name), calling findRenderTasksInDependencies()
    // - sort the tasks preferring those whose project name equals 'core', then lexigraphical by path
    // - for each task get output dir to create relative or absolute link
    // NOTE: explicitly exclude solr/test-framework, or attempting to link to lucene-test-framework because if we did javadoc would
    // attempt to link class refs in in org.apache.lucene, causing broken links. (either broken links to things like "Directory" if
    // lucene-test-framework was first, or broken links to things like LuceneTestCase if lucene-core was first)
    if (project.path != ':solr:test-framework') {  //
      findRenderTasksInDependencies()
        .sort(false, Comparator.comparing { (it.project.name != 'core') as Boolean }.thenComparing(Comparator.comparing { it.path }))
        .each { otherTask ->
          def otherProject = otherTask.project
          // For relative links we compute the actual relative link between projects.
          def crossLuceneSolr = (otherProject.docroot != project.docroot)
          if (relativeProjectLinks && !crossLuceneSolr) {
            def pathTo = otherTask.outputDir.toPath().toAbsolutePath()
            def pathFrom = outputDir.toPath().toAbsolutePath()
            def relative = pathFrom.relativize(pathTo).toString().replace(File.separator, '/')
            opts << ['-link', relative]
          } else {
            // For absolute links, we determine the target URL by assembling the full URL.
            def base = otherProject.path.startsWith(":lucene") ? luceneDocUrl : solrDocUrl
            allOfflineLinks.put("${base}/${otherProject.relativeDocPath}/".toString(), otherTask.outputDir)
          }
        }
    }
    
    // Add offline links.
    allOfflineLinks.each { url, dir ->
      // Some sanity check/ validation here to ensure dir/package-list or dir/element-list is present.
      if (!project.file("$dir/package-list").exists() &&
          !project.file("$dir/element-list").exists()) {
        throw new GradleException("Expected pre-rendered package-list or element-list at ${dir}.")
      }
      opts << [ '-linkoffline', url, dir ]
    }

    opts << [ '--release', 11 ]
    opts << '-Xdoclint:all,-missing'

    // Temporary file that holds all javadoc options for the current task.
    optionsFile.withWriter("UTF-8", { writer ->
      // escapes an option with single quotes or whitespace to be passed in the options.txt file for
      def escapeJavadocOption = { String s -> (s =~ /[ '"]/) ? ("'" + s.replaceAll(/[\\'"]/, /\\$0/) + "'") : s }

      opts.each { entry ->
        if (entry instanceof List) {
          writer.write(entry.collect { escapeJavadocOption(it as String) }.join(" "))
        } else {
          writer.write(escapeJavadocOption(entry as String))
        }
        writer.write('\n')
      }
    })

    def javadocCmd = {
      if (executable == null) {
        JavaInstallationRegistry registry = project.extensions.getByType(JavaInstallationRegistry)
        JavaInstallation currentJvm = registry.installationForCurrentVirtualMachine.get()
        return currentJvm.jdk.get().javadocExecutable.asFile
      } else {
        return project.file(executable)
      }
    }()

    logger.info("Javadoc executable used: ${javadocCmd}")

    def outputFile = project.file("${getTemporaryDir()}/javadoc-output.txt")
    def result

    outputFile.withOutputStream { output ->
      result = project.exec {
        executable javadocCmd

        // we want to capture both stdout and stderr to the same
        // stream but gradle attempts to close these separately
        // (it has two independent pumping threads) and it can happen
        // that one still tries to write something when the other closed
        // the underlying output stream.
        def wrapped = new java.io.FilterOutputStream(output) {
          public void close() { 
            // no-op. we close this stream manually.
          }
        }
        standardOutput = wrapped
        errorOutput = wrapped

        args += [ "@${optionsFile}" ]

        // -J flags can't be passed via options file... (an error "javadoc: error - invalid flag: -J-Xmx512m" occurs.)
        args += [ "-J-Xmx512m" ]
        // force locale to be "en_US" (fix for: https://bugs.openjdk.java.net/browse/JDK-8222793)
        args += [ "-J-Duser.language=en", "-J-Duser.country=US" ]

        ignoreExitValue true
      }

      logger.lifecycle("Exec returned: ${result}")
    }

    if (result.getExitValue() != 0) {
      // Pipe the output to console. Intentionally skips any encoding conversion 
      // and pumps raw bytes.
      System.out.write(outputFile.bytes)

      def cause
      try {
        result.rethrowFailure()
      } catch (ex) {
        cause = ex
      }
      throw new GradleException("Javadoc generation failed for ${project.path},\n  Options file at: ${optionsFile}\n  Command output at: ${outputFile}", cause)
    }

    // append some special table css, prettify css
    ant.concat(destfile: "${outputDir}/stylesheet.css", append: "true", fixlastline: "true", encoding: "UTF-8") {
      filelist(dir: taskResources, files: "table_padding.css")
      filelist(dir: project.file("${taskResources}/prettify"), files: "prettify.css")
    }

    // append prettify to scripts
    ant.concat(destfile: "${outputDir}/script.js", append: "true", fixlastline: "true", encoding: "UTF-8") {
      filelist(dir: project.file("${taskResources}/prettify"), files: "prettify.js inject-javadocs.js")
    }

    ant.fixcrlf(srcdir: outputDir, includes: "stylesheet.css script.js", eol: "lf", fixlast: "true", encoding: "UTF-8")
  }
}
