package org.implab.gradle.variants;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.gradle.api.Action;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.implab.gradle.common.core.lang.Deferred;
import org.implab.gradle.common.sources.GenericSourceSet;
import org.implab.gradle.common.sources.SourcesPlugin;
import org.implab.gradle.variants.core.Layer;
import org.implab.gradle.variants.core.Variant;
import org.implab.gradle.variants.core.VariantsExtension;
import org.implab.gradle.variants.core.VariantsView;
import org.implab.gradle.variants.sources.CompileUnit;
import org.implab.gradle.variants.sources.CompileUnitsView;
import org.implab.gradle.variants.sources.RoleProjectionsView;
import org.implab.gradle.variants.sources.SourceSetMaterializer;
import org.implab.gradle.variants.sources.VariantSourcesContext;

@NonNullByDefault
public abstract class VariantSourcesPlugin implements Plugin<Project> {
    @Override
    public void apply(Project target) {
        // Apply the main VariantsPlugin to ensure the core variant model is available.
        target.getPlugins().apply(VariantsPlugin.class);
        target.getPlugins().apply(SourcesPlugin.class);
        // Access the VariantsExtension to configure variant sources.
        var variantsExtension = target.getExtensions().getByType(VariantsExtension.class);
        var objectFactory = target.getObjects();

        var sources = SourcesPlugin.getSourcesExtension(target);

        var deferred = new Deferred<VariantSourcesContext>();

        variantsExtension.whenFinalized(variants -> {
            var compileUnits = CompileUnitsView.of(variants);
            var roleProjections = RoleProjectionsView.of(variants);

            var context = new Context(variants, compileUnits, roleProjections);

            deferred.resolve(context);
        });

        // var

    }

    private static class Context implements VariantSourcesContext {

        private final VariantsView variantsView;
        private final CompileUnitsView compileUnitsView;
        private final RoleProjectionsView roleProjectionsView;

        Context(VariantsView variantsView, CompileUnitsView compileUnitsView, RoleProjectionsView roleProjectionsView) {
            this.variantsView = variantsView;
            this.compileUnitsView = compileUnitsView;
            this.roleProjectionsView = roleProjectionsView;
        }

        @Override
        public VariantsView getVariants() {
            return variantsView;
        }

        @Override
        public CompileUnitsView getCompileUnits() {
            return compileUnitsView;
        }

        @Override
        public RoleProjectionsView getRoleProjections() {
            return roleProjectionsView;
        }

        @Override
        public SourceSetMaterializer getSourceSets() {
            // TODO Auto-generated method stub
            throw new UnsupportedOperationException("Unimplemented method 'getSourceSets'");
        }

        @Override
        public void configureLayer(Layer layer, Action<? super GenericSourceSet> action) {
            // TODO Auto-generated method stub
            throw new UnsupportedOperationException("Unimplemented method 'configureLayer'");
        }

        @Override
        public void configureVariant(Variant variant, Action<? super GenericSourceSet> action) {
            // TODO Auto-generated method stub
            throw new UnsupportedOperationException("Unimplemented method 'configureVariant'");
        }

        @Override
        public void configureUnit(CompileUnit unit, Action<? super GenericSourceSet> action) {
            // TODO Auto-generated method stub
            throw new UnsupportedOperationException("Unimplemented method 'configureUnit'");
        }

    }


}
