package org.implab.gradle.common.sources;

import java.util.ArrayList;
import java.util.Objects;

import javax.inject.Inject;

import org.gradle.api.InvalidUserDataException;
import org.gradle.api.Named;
import org.gradle.api.provider.ListProperty;

/**
 * Role binding inside a variant, points to layer names.
 */
public abstract class BuildRole implements Named {
    private final String name;
    private boolean finalized;

    @Inject
    public BuildRole(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    public abstract ListProperty<String> getLayers();

    /**
     * Binds this role to one or more declared layers.
     */
    public void layers(String layer, String... extra) {
        ensureMutable("add role layers");

        var values = new ArrayList<String>(1 + extra.length);

        values.add(Objects.requireNonNull(layer, "Layer name is required"));
        for (var item : extra)
            values.add(Objects.requireNonNull(item, "Layer name is required"));

        getLayers().addAll(values);
    }

    void finalizeModel() {
        if (finalized)
            return;

        getLayers().finalizeValue();
        getLayers().disallowChanges();
        finalized = true;
    }

    private void ensureMutable(String operation) {
        if (finalized)
            throw new InvalidUserDataException("Role '" + name + "' is finalized and cannot " + operation);
    }
}
