package org.implab.gradle.common.json.core;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Predicate;

import org.gradle.api.Action;
import org.implab.gradle.common.core.lang.Closures;

import groovy.lang.Closure;

/**
 * Простая include/exclude-маска по ключам верхнего уровня.
 */
public class MapImportSpec {

    private final Set<String> includes = new LinkedHashSet<>();
    private final Set<String> excludes = new LinkedHashSet<>();

    public void include(String... keys) {
        includes.addAll(Arrays.asList(keys));
    }

    public void exclude(String... keys) {
        excludes.addAll(Arrays.asList(keys));
    }

    public Set<String> getIncludes() {
        return includes;
    }

    public Set<String> getExcludes() {
        return excludes;
    }

    public boolean hasIncludes() {
        return !includes.isEmpty();
    }

    public boolean isExcluded(String key) {
        return excludes.contains(key);
    }

    public boolean isIncluded(String key) {
        return !hasIncludes() || includes.contains(key);
    }

    public boolean matches(String key) {
        return isIncluded(key) && !isExcluded(key);
    }

    public Predicate<String> toPredicate() {
        return this::matches;
    }

    public static Predicate<String> buildPredicate(Action<? super MapImportSpec> action) {
        var spec = new MapImportSpec();
        action.execute(spec);
        return spec.toPredicate();
    }

    public static Predicate<String> buildPredicate(Closure<?> closure) {
        return buildPredicate(Closures.action(closure));
    }
}
