package org.kravemir.lightvalue;

import org.gradle.api.*;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSet;

import java.io.File;

/**
 * {@link LightValuePlugin} provides setups LightValue functionality with conventions.
 *
 * To use without default conventions, use {@link LightValueBasePlugin}.
 *
 * @see <a href="https://guides.gradle.org/designing-gradle-plugins/#capabilities-vs-conventions">
 *          Designing Gradle plugins: Capabilities vs. conventions</a>
 */
public class LightValuePlugin implements Plugin<Project> {

    @Override
    public void apply(final Project project) {
        project.getPlugins().apply(LightValueBasePlugin.class);

        project.getPlugins().withType(JavaBasePlugin.class, javaBasePlugin -> {
            final NamedDomainObjectContainer<LightValueConfiguration> lightValueContainer = getContainer(project);

            JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class);
            java.getSourceSets().all(sourceSet -> createConfigurationForSourceSet(lightValueContainer, sourceSet));
        });
    }

    private void createConfigurationForSourceSet(
            NamedDomainObjectContainer<LightValueConfiguration> lightValueContainer,
            SourceSet sourceSet
    ) {
        final String name = sourceSet.getName();
        LightValueConfiguration configuration = lightValueContainer.create(name);
        Project project = configuration.getTask().getProject();

        File srcDir = project.file(String.format("%s/src/%s/model", project.getProjectDir().getPath(), name));
        File outDir = project.file(String.format("%s/generated/lightValue/%s", project.getBuildDir().getPath(), name));

        configuration.source(srcDir);
        configuration.setOutputDir(outDir);
        configuration.registerInSourceSets(sourceSet);
    }

    @SuppressWarnings("unchecked") // TODO: get rid of this, use some non-generic class / way to get it
    public NamedDomainObjectContainer<LightValueConfiguration> getContainer(Project project) {
        return (NamedDomainObjectContainer<LightValueConfiguration>) project.getExtensions().getByName("lightvalue");
    }
}
