package System::Introspector::Gatherer;
use Moo;
use Object::Remote;
use Object::Remote::Future;
use System::Introspector::Gatherer::Bridge;
use Module::Runtime qw( use_module );

sub gather {
    my ($self, $class, $args) = @_;
    return use_module("System::Introspector::Probe::$class")
        ->new($args)
        ->gather;
}

sub _new_direct {
    my ($class, $remote) = @_;
    return $class->new::on($remote);
}

sub _new_bridged {
    my ($class, $bridge, $remote) = @_;
    return System::Introspector::Gatherer::Bridge->new::on($bridge,
        remote_spec  => $remote,
        remote_class => $class,
    );
}

sub new_from_spec {
    my ($class, %arg) = @_;
    my ($user, $host, $sudo_user) = @arg{qw( user host sudo_user )};
    my $sudo = defined($sudo_user) ? sprintf('%s@', $sudo_user) : undef;
    if (defined $host) {
        my $remote = join '@', grep defined, $user, $host;
        if (defined $sudo_user) {
            return $class->_new_bridged($remote, $sudo);
        }
        else {
            return $class->_new_direct($remote);
        }
    }
    else {
        if (defined $sudo_user) {
            return $class->_new_direct($sudo);
        }
        else {
            return $class->new;
        }
    }
}

1;
