use strictures 1;

package System::Introspector::Util;
use Exporter 'import';
use IPC::Run qw( run );

our @EXPORT_OK = qw(
    handle_from_command
    handle_from_file
    output_from_command
    output_from_file
    lines_from_command
    files_from_dir
    transform_exceptions
);

sub files_from_dir {
    my ($dir) = @_;
    my $dh;
    opendir $dh, $dir
        or die "Unable to read directory $dir: $!\n";
    my @files;
    while (defined( my $item = readdir $dh )) {
        next if -d "$dir/$item";
        push @files, $item;
    }
    return @files;
}

sub transform_exceptions (&) {
    my ($code) = @_;
    local $@;
    my $result = eval { $code->() };
    return { error => "$@" }
        if $@;
    return $result;
}

sub output_from_command {
    my ($command, $in) = @_;
    $in = ''
        unless defined $in;
    my ($out, $err) = ('', '');
    my $ok = run($command, \$in, \$out, \$err);
    return $out, $err, $ok
        if wantarray;
    $command = join ' ', @$command
        if ref $command;
    die "Error running command ($command): $err\n"
        unless $ok;
    return $out;
}

sub lines_from_command {
    my ($command) = @_;
    my $output = output_from_command $command;
    chomp $output;
    return split m{\n}, $output;
}

sub handle_from_command {
    my ($command) = @_;
    open my $pipe, '-|', $command
        or die "Unable to read from command '$command': $!\n";
    return $pipe;
}

sub handle_from_file {
    my ($file) = @_;
    open my $fh, '<', $file
        or die "Unable to read $file: $!\n";
    return $fh;
}

sub output_from_file {
    my ($file) = @_;
    my $fh = handle_from_file $file;
    return <$fh>
        if wantarray;
    return do { local $/; <$fh> };
}

1;
