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

/*
 * Aggregate Javadoc is not published to Maven Central. Each Java module that is published
 * to Maven Cental packages its own Javadoc. To generate aggregated javadocs, run:
 *   ./gradlew :sdks:java:javadoc:aggregateJavadoc
 * Generated files will be located under beam/sdks/java/javadoc/build/docs/javadoc and are
 * used as part of the beam-site source tree.
 */
plugins { id 'org.apache.beam.module' }
applyJavaNature(publish: false)
description = "Apache Beam :: SDKs :: Java :: Aggregated Javadoc"

for (p in rootProject.subprojects) {
  if (!p.path.equals(project.path) && !p.path.equals(':sdks:java:bom')) {
    evaluationDependsOn(p.path)
  }
}

ext.getExportedJavadocProjects = {
  def exportedJavadocProjects = new ArrayList<>();
  for (p in rootProject.subprojects) {
    if (!p.path.equals(project.path) && !p.path.equals(':sdks:java:bom')) {
      def subproject = p // project(':' + p.name)
      if (subproject.ext.properties.containsKey('exportJavadoc') &&
          subproject.ext.properties.exportJavadoc) {
        exportedJavadocProjects.add(p.path)
      }
    }
  }
  return exportedJavadocProjects
}

task allJavadoc() {
  def exportedJavadocProjects = getExportedJavadocProjects()
  dependsOn exportedJavadocProjects.collect { "$it:javadoc" }
}

task aggregateJavadoc(type: Javadoc) {
  def createJavadocIOUrlForDependency = {
    def dependency = dependencies.create(it)
    return 'https://static.javadoc.io/' + dependency.getGroup() + '/' + dependency.getName() + '/' + dependency.getVersion()
  }

  def exportedJavadocProjects = getExportedJavadocProjects()
  source exportedJavadocProjects.collect { project(it).sourceSets.main.allJava }
  classpath = files(exportedJavadocProjects.collect { project(it).sourceSets.main.compileClasspath })
  destinationDir = file("${buildDir}/docs/javadoc")

  exclude "org/apache/beam/examples/*"
  exclude "org/apache/beam/fn/harness/*"
  exclude "org/apache/beam/runners/apex/translation/*"
  exclude "org/apache/beam/runners/core/*"
  exclude "org/apache/beam/runners/dataflow/internal/*"
  exclude "org/apache/beam/runners/flink/examples/*"
  exclude "org/apache/beam/runners/flink/translation/*"
  exclude "org/apache/beam/runners/spark/examples/*"
  exclude "org/apache/beam/runners/spark/translation/*"
  exclude "org/apache/beam/sdk/transforms/reflect/*"
  exclude "org/apache/beam/sdk/runners/*"
  exclude "org/apache/beam/sdk/util/*"

  options.with {
    failOnError false
    title "Apache Beam " + project.version
    overview 'overview.html'
    for (dep in project.library.java.values()) {
      links createJavadocIOUrlForDependency(dep)
    }
  }
}
