package org.implab.gradle.common.utils.os;

import java.io.File;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import org.implab.gradle.common.utils.OperatingSystem;
import org.implab.gradle.common.utils.Values;

class GenericSystem implements OperatingSystem {

    private final String name;

    private final String version;

    GenericSystem(String name, String version) {
        this.name = name;
        this.version = version;
    }

    public String getPathVar() {
        return "PATH";
    }

    @Override
    public String family() {
        return OperatingSystem.UNKNOWN_FAMILY;
    }

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

    @Override
    public String version() {
        return version;
    }

    protected Stream<File> getPath() {
        String path = System.getenv(getPathVar());
        return path == null
                ? Stream.empty()
                : Arrays.stream(path.split(Pattern.quote(File.pathSeparator)))
                        .map(File::new);
    }

    protected Function<File, Stream<File>> candidates(String cmd) {
        return base -> Stream.of(new File(base, cmd));
    }

    @Override
    public Optional<File> which(String cmd) {
        return getPath().flatMap(candidates(cmd)).filter(File::isFile).findAny();
    }

    @Override
    public Optional<File> which(String cmd, Iterable<? extends File> paths) {
        return Values.stream(paths.iterator()).flatMap(candidates(cmd)).filter(File::isFile).findAny();
    }
}
