package nu.studer.gradle.rocker;

import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ModuleVersionSelector;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.util.GradleVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings("unused")
public class RockerPlugin implements Plugin<Project> {

    private static final Logger LOGGER = LoggerFactory.getLogger(RockerPlugin.class);

    @Override
    public void apply(Project project) {
        // apply Java base plugin, making it possible to also use the rocker plugin for Android builds
        project.getPlugins().apply(JavaBasePlugin.class);

        // allow to configure the rocker version via extension property
        RockerVersion.applyDefaultVersion(project);

        // use the configured rocker version on all rocker dependencies
        enforceRockerVersion(project);

        // add rocker DSL extension
        NamedDomainObjectContainer<RockerConfig> container = project.container(RockerConfig.class, name -> new RockerConfig(name, project));
        project.getExtensions().add("rocker", container);

        // create configuration for the runtime classpath of the rocker compiler (shared by all rocker configuration domain objects)
        final Configuration configuration = createRockerCompilerRuntimeConfiguration(project);

        // create a rocker task for each rocker configuration domain object
        container.all(config -> {
            // create rocker task
            RockerCompile rocker = project.getTasks().create(config.getCompileTaskName(), RockerCompile.class);
            rocker.setDescription("Invokes the Rocker template engine.");
            rocker.setGroup("Rocker");
            rocker.setConfig(config);
            rocker.setRuntimeClasspath(configuration);

            // wire task dependencies such that the rocker task creates the sources before the corresponding Java compile task compiles them and
            // add the rocker-runtime to the compile configuration in order to be able to compile the generated sources
            SourceSetContainer sourceSets = project.getConvention().getPlugin(JavaPluginConvention.class).getSourceSets();
            SourceSet sourceSet = sourceSets.findByName(config.name);
            if (sourceSet != null) {
                project.getTasks().getByName(sourceSet.getCompileJavaTaskName()).dependsOn(rocker);
                project.getDependencies().add(getCompileConfigurationName(sourceSet), "com.fizzed:rocker-runtime");
            }
        });
    }

    /**
     * For older gradle versions we fall back to `compile`.
     * Newer gradle versions will use `implementation` instead of the deprecated `compile` configuration.
     * */
    private String getCompileConfigurationName(SourceSet sourceSet) {
        return isAtLeastGradle5() ? sourceSet.getImplementationConfigurationName() : sourceSet.getCompileConfigurationName();
    }

    private boolean isAtLeastGradle5() {
        return GradleVersion.current().compareTo(GradleVersion.version("5.0")) >= 0;
    }

    private void enforceRockerVersion(final Project project) {
        project.getConfigurations().all(configuration ->
            configuration.getResolutionStrategy().eachDependency(details -> {
                ModuleVersionSelector requested = details.getRequested();
                if (requested.getGroup().equals("com.fizzed") && requested.getName().startsWith("rocker-")) {
                    details.useVersion(RockerVersion.fromProject(project).asString());
                }
            })
        );
    }

    private Configuration createRockerCompilerRuntimeConfiguration(Project project) {
        Configuration rockerCompilerRuntime = project.getConfigurations().create("rockerCompiler");
        rockerCompilerRuntime.setDescription("The classpath used to invoke the Rocker template engine. Add your additional dependencies here.");
        project.getDependencies().add(rockerCompilerRuntime.getName(), "com.fizzed:rocker-compiler");
        project.getDependencies().add(rockerCompilerRuntime.getName(), "org.slf4j:slf4j-simple:1.7.25");
        return rockerCompilerRuntime;
    }

}

@@ -429,46 +429,8 @@
 er;%0A
-import org.gradle.util.GradleVersion;%0A
 impo
@@ -2681,622 +2681,110 @@
 add(
-getCompileConfigurationName(sourceSet), %22com.fizzed:rocker-runtime%22);%0A            %7D%0A        %7D);%0A    %7D%0A%0A    /**%0A     * For older gradle versions we fall back to %60compile%60.%0A     * Newer gradle versions will use %60implementation%60 instead of the deprecated %60compile%60 configuration.%0A     * */%0A    private String getCompileConfigurationName(SourceSet sourceSet) %7B%0A        return isAtLeastGradle5() ? sourceSet.getImplementationConfigurationName() : sourceSet.getCompileConfigurationName(
+sourceSet.getImplementationConfigurationName(), %22com.fizzed:rocker-runtime%22
 );%0A    
-%7D%0A%0A
+ 
     
-private boolean isAtLeastGradle5() %7B%0A        return GradleVersion.current().compareTo(GradleVersion.version(%225.0%22)) %3E= 0
+   %7D%0A        %7D)
 ;%0A  
@@ -2826,22 +2826,16 @@
 Version(
-final 
 Project 

Simplify now that Gradle 5.0 is the minimum supported version