package IPC::Run3::ProfLogReader;

$VERSION = 0.000_1;

=head1 NAME

IPC::Run3::ProfLogReader -  Read an IPC::Run3::ProfLogger file and dispatch it

=head1 SYNOPSIS

    use IPC::Run3::ProfLogReader;

    my $r = IPC::Run3::ProfLogReader->new; ## use "run3.out"
    my $r = IPC::Run3::ProfLogReader->new( Source => $fn );

    my $p = IPC::Run3::ProfPP;   ## For example
    my $r = IPC::Run3::ProfLogReader->new( ..., Handler => $p );

    $r->read;
    $r->read_all;

=head1 DESCRIPTION

Reads a log file.  Use the filename "-" to read from STDIN.

=cut

use strict;

sub new {
    my $class = ref $_[0] ? ref shift : shift;
    my $self = bless { @_ }, $class;
    
    $self->{Source} = "run3.out"
        unless defined $self->{Source} && length $self->{Source};

    my $source = $self->{Source};

    if ( ref $source eq "GLOB" || UNIVERSAL::isa( $source, "IO::Handle" ) ) {
        $self->{FH} = $source;
    }
    elsif ( $source eq "-" ) {
        $self->{FH} = \*STDIN;
    }
    else {
        open PROFILE, "<$self->{Source}" or die "$!: $self->{Source}\n";
        $self->{FH} = *PROFILE{IO};
    }
    return $self;
}


sub set_handler { $_[0]->{Handler} = $_[1] }

sub get_handler { $_[0]->{Handler} }

sub read {
    my $self = shift;

    my $fh = $self->{FH};
    my @ln = split / /, <$fh>;

    return 0 unless @ln;
    return 1 unless $self->{Handler};

    chomp $ln[-1];

    ## Ignore blank and comment lines.
    return 1 if @ln == 1 && ! length $ln[0] || 0 == index $ln[0], "#";

    if ( $ln[0] eq "\\app_call" ) {
        shift @ln;
        my @times = split /,/, pop @ln;
        $self->{Handler}->app_call(
            [
                map {
                    s/\\\\/\\/g;
                    s/\\_/ /g;
                    $_;
                } @ln
            ],
            @times
        );
    }
    elsif ( $ln[0] eq "\\app_exit" ) {
        shift @ln;
        $self->{Handler}->app_exit( pop @ln, @ln );
    }
    else {
        my @times = split /,/, pop @ln;
        $self->{Handler}->run_exit(
            [
                map {
                    s/\\\\/\\/g;
                    s/\\_/ /g;
                    $_;
                } @ln
            ],
            @times
        );
    }

    return 1;
}


sub read_all {
    my $self = shift;

    1 while $self->read;

    return 1;
}


=head1 LIMITATIONS

=head1 COPYRIGHT

    Copyright 2003, R. Barrie Slaymaker, Jr., All Rights Reserved

=head1 LICENSE

You may use this module under the terms of the BSD, Artistic, or GPL licenses,
any version.

=head1 AUTHOR

Barrie Slaymaker <barries@slaysys.com>

=cut

1;