package org.implab.gradle.variants.sources.internal;

import org.gradle.api.Action;
import org.gradle.api.file.Directory;
import org.gradle.api.provider.Provider;
import org.implab.gradle.common.core.lang.FilePaths;
import org.implab.gradle.variants.sources.CompileUnitSourceSetSpec;

/**
 * Applies the default layout policy for source sets materialized from variant
 * compile units.
 *
 * <p>
 * The convention keeps sources grouped by layer and outputs grouped by
 * variant/layer. It only sets directory properties on the materialized source
 * set; declaring source directories and named outputs remains the
 * responsibility of adapters or user DSL.
 * </p>
 */
public class CompileUnitLayoutConvention implements Action<CompileUnitSourceSetSpec> {
    private final Provider<Directory> sourcesBaseDir;
    private final Provider<Directory> outputsBaseDir;

    public CompileUnitLayoutConvention(
            Provider<Directory> baseDirectory,
            Provider<Directory> outputsBaseDir) {
        this.sourcesBaseDir = baseDirectory;
        this.outputsBaseDir = outputsBaseDir;
    }

    @Override
    public void execute(CompileUnitSourceSetSpec spec) {
        var sourceSet = spec.getSourceSet();
        var unit = spec.getCompileUnit();
        var layerName = unit.layer().getName();
        var variantName = unit.variant().getName();

        sourceSet.getSourceSetDir()
                .convention(sourcesBaseDir.map(base -> base.dir(FilePaths.cat(layerName))));

        sourceSet.getOutputsDir()
                .convention(outputsBaseDir.map(base -> base.dir(FilePaths.cat(variantName, layerName))));
    }

}
