package Common::File::Tied::Parsed;
use strict;

use lib '/app/tools/common/lib';
use Common::File::Tied::LineParser::Factory;

use base 'Common::File::Tied';

# This class extends the Common::File::Tied interface to return an array reference of parsed data
# rather than a string.
#
sub _init {
    my ( $self, $file ) = @_;

    # We'll need to figure out how to parse lines in this file before we can complete
    # the initialization.  For example, we will need to be able to tell whether lines
    # we read are 'complete', or whether we actually hit a quoted \n.
    #
    $self->{lineParser} = Common::File::Tied::LineParser::Factory->CreateParser($file);

    # Call the inherited method first.
    #
    return $self->SUPER::_init($file);
}

# Certain encoding schemes (like CSV files) allow for newlines or carriage returns
# to appear within 'quoted' sections.  These should not be treated as actual end-of-line
# markers.   Perl's <FH> mechanism won't help us with these.
# So we'll rely on the LineParser class to let us know whether a line is complete or not.
#
sub _readNextLineFromFile {
    my ($self) = @_;

    my $line = $self->{file}->readLine();

    while ( defined $line && !$self->{lineParser}->lineIsComplete($line) ) {
        my $nextLine = $self->{file}->readLine();
        last unless defined $nextLine;
        $line .= $nextLine;
    }
    return $line;
}

# Implement with a private method so we can subclass sensibly.
# !!! We might want to cache the last line read, to make accessing the
#     same line over and over again more efficient.
#
sub _readLine {
    my ( $self, $index ) = @_;

    # Call the inherited method to get the string.
    #
    my $line = $self->SUPER::_readLine($index);

    return [] unless $line;

    # Remove the newline.
    #
    chomp($line);

    return $self->{lineParser}->parseString($line);
}

1;
