package org.implab.gradle.common.exec;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.implab.gradle.common.utils.Exceptions;

@NonNullByDefault
public interface ShellExec extends PipeBuilder, EnvironmentBuilder {

    default CompletableFuture<List<String>> readAllLines() throws IOException {
        List<String> lines = new ArrayList<>();
        stdout(RedirectTo.consumer(lines::add));

        return exec()
            .thenAccept(Exceptions.unchecked(this::assertExitCode))
            .thenApply(v -> lines);
    }

    default CompletableFuture<String> readAllText() throws IOException {
        List<String> lines = new ArrayList<>();
        stdout(RedirectTo.consumer(lines::add));

        return exec()
                .thenAccept(Exceptions.unchecked(this::assertExitCode))
                .thenApply(v -> String.join("\n", lines));
    }

    default void assertExitCode(Integer code) throws IOException {
        if (code != 0)
            throw new IOException(String.format("The process is terminated with code %d", code));
    }

    CompletableFuture<Integer> exec() throws IOException;
}
