package io.freefair.gradle.plugins.maven.javadoc;

import lombok.Getter;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.internal.file.FileTreeInternal;
import org.gradle.api.internal.file.UnionFileCollection;
import org.gradle.api.internal.file.UnionFileTree;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.javadoc.Javadoc;
import org.gradle.external.javadoc.StandardJavadocDocletOptions;

import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

@Getter
public class AggregateJavadocPlugin implements Plugin<Project> {

    private Javadoc aggregateJavadoc;

    @Override
    public void apply(Project project) {
        aggregateJavadoc = project.getTasks().create("aggregateJavadoc", Javadoc.class);
        aggregateJavadoc.setGroup(JavaBasePlugin.DOCUMENTATION_GROUP);

        project.getPlugins().withType(JavaPlugin.class, javaPlugin -> {
            aggregateJavadoc.setDestinationDir(new File(
                    project.getConvention().getPlugin(JavaPluginConvention.class).getDocsDir(),
                    "aggregateJavadoc"
            ));
        });

        project.afterEvaluate(p -> {

            List<Javadoc> javadocTasks = project.getAllprojects().stream()
                    .peek(sub -> project.evaluationDependsOn(sub.getPath()))
                    .filter(sub -> sub.getPlugins().hasPlugin(JavaPlugin.class))
                    .map(sub -> (Javadoc) sub.getTasks().getByName(JavaPlugin.JAVADOC_TASK_NAME))
                    .collect(Collectors.toList());

            aggregateJavadoc.setClasspath(new UnionFileCollection(
                    javadocTasks.stream().map(Javadoc::getClasspath).collect(Collectors.toList())
            ));

            aggregateJavadoc.setSource(new UnionFileTree(
                    "aggregated sources",
                    javadocTasks.stream().map(Javadoc::getSource)
                            .map(FileTreeInternal.class::cast)
                            .collect(Collectors.toList())
            ));

            StandardJavadocDocletOptions aggregateJavadocOptions = (StandardJavadocDocletOptions) aggregateJavadoc.getOptions();

            javadocTasks.forEach(jd -> {
                StandardJavadocDocletOptions javadocOptions = (StandardJavadocDocletOptions) jd.getOptions();

                javadocOptions.getLinks().forEach(link -> {
                    if (!aggregateJavadocOptions.getLinks().contains(link)) {
                        aggregateJavadocOptions.links(link);
                    }
                });

                javadocOptions.getLinksOffline().forEach(offlineLink -> {
                    if (!aggregateJavadocOptions.getLinksOffline().contains(offlineLink)) {
                        aggregateJavadocOptions.getLinksOffline().add(offlineLink);
                    }
                });

                javadocOptions.getJFlags().forEach(jFlag -> {
                    if (!aggregateJavadocOptions.getJFlags().contains(jFlag))
                        aggregateJavadocOptions.jFlags(jFlag);
                });
            });
        });


    }
}

@@ -44,16 +44,156 @@
 vadoc;%0A%0A
+import java.io.File;%0Aimport java.util.List;%0Aimport java.util.Optional;%0Aimport java.util.stream.Collectors;%0Aimport java.util.stream.Stream;%0A%0A
 import l
@@ -684,89 +684,8 @@
 s;%0A%0A
-import java.io.File;%0Aimport java.util.List;%0Aimport java.util.stream.Collectors;%0A%0A
 @Get
@@ -1029,64 +1029,30 @@
 ect.
-getPlugins().withType(Ja
+afterE
 va
-P
 lu
-gin.class, javaPlugin
+ate(p
  -%3E %7B%0A
+%0A
     
@@ -1051,32 +1051,36 @@
  %7B%0A%0A            
+if (
 aggregateJavadoc
@@ -1080,17 +1080,17 @@
 Javadoc.
-s
+g
 etDestin
@@ -1102,17 +1102,20 @@
 Dir(
-new File(
+) == null) %7B
 %0A   
@@ -1123,28 +1123,59 @@
             
-    
+File docsDir = Optional.ofNullable(
 project.getC
@@ -1186,19 +1186,20 @@
 ntion().
-get
+find
 Plugin(J
@@ -1228,22 +1228,9 @@
 ass)
-.getDocsDir(),
+)
 %0A   
@@ -1250,51 +1250,134 @@
     
-%22aggregateJavadoc%22%0A            
+    .map(JavaPluginConvention::getDocsDir)%0A                        .orElse(new File(project.getBuildDir(), %22docs%22
 ));%0A
+%0A
         
 %7D);%0A
@@ -1372,29 +1372,24 @@
         
-%7D);%0A%0A
         
 project.
@@ -1384,78 +1384,213 @@
     
-project.afterEvaluate(p -%3E %7B%0A%0A            List%3CJavadoc%3E javadocTasks =
+aggregateJavadoc.setDestinationDir(new File(docsDir, %22aggregateJavadoc%22));%0A            %7D%0A%0A            List%3CJavadoc%3E javadocTasks = Stream.concat(%0A                    Stream.of(project),%0A                   
  pro
@@ -1601,11 +1601,11 @@
 .get
-All
+Sub
 proj
@@ -1620,16 +1620,24 @@
 tream()%0A
+        
         
@@ -1705,16 +1705,30 @@
 ath()))%0A
+            )%0A
         
@@ -3392,16 +3392,18 @@
 (jFlag))
+ %7B
 %0A       
@@ -3458,16 +3458,38 @@
 jFlag);%0A
+                    %7D%0A
         

Fix aggregate javadoc plugin