# Copyright (C) 2000-2004 Stichting LogReport Foundation LogReport@LogReport.org

# This file is part of Lire.

# Lire is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program (see COPYING); if not, check with
# http://www.gnu.org/copyleft/gpl.html.
#
# Authors:
#   Wessel Dankers <wsl@logreport.org>
#   Francis J. Lacoste <flacoste@logreport.org>
#   Francis J. Lacoste <flacoste@logreport.org>

package Lire::DlfConverters::Lprng;

use strict;

use base qw/Lire::DlfConverter/;

use Lire::Time qw(date2cal getMonthName);

use Carp;

sub new {
    return bless {}, shift;
}

sub name { return 'lprng_account'; }

sub title { return 'LPRNG printer server page log'; }

sub description {
    return '<para>This DlfConverter converts LPRNG accounting file to the <structname>print</structname> schema.</para>';
}

sub schemas { return qw/print/; }

sub handle_log_lines { return 1; }

sub parse_time {
    my $self = $_[0];

    my ($year, $month, $day, $time, $msec) =
      $_[0] =~ /^(\d\d\d\d)-(\d\d)-(\d\d)-(\d\d:\d\d:\d\d).(\d\d\d)$/
        or die "bad time field: $_[0]\n";

    return date2cal($year, getMonthName($month-1), $day, $time) . '.' . $msec;
}

sub init_dlf_converter {
    my ($self, $process) = @_;
    $self->{'cache'} = {};
    return;
}

sub process_log_line {
    my ($self, $process, $line) = @_;

    # Keys are
    #  H = client host
    #  k = job-id
    #  b = size
    #  t = time
    #  n = user
    #  P = printer
    my %rec = $line =~ /'-(.)(.*?)'/g;
    unless ( %rec ) {
        $process->error( "failed to parse LPR-NG accounting record", $line );
        return;
    }

    foreach my $f ( qw/k t/ ) {
        if ( ! $rec{$f} ) {
            $process->error( "missing '$f' field", $line );
            return;
        }
    }

    my $time  = eval { parse_time($rec{'t'}) };
    if ( $@ ) {
        $process->error( $@, $line );
        return;
    }

    my $jobid = $rec{'k'};
    if ( $line =~ /^jobstart/) {
        $self->{'cache'}{$jobid} = {
                                    'time' => $time,
                                    'job-id' => $jobid,
                                   };
    } elsif ( $line =~ /^jobend/) {
        my $job;
        if ( ! exists $self->{'cache'}{$jobid}) {
            $job = {
                    'time' => $time,
                    'job-id' => $jobid
                   };
        } else {
            $job = $self->{'cache'}{$jobid};
        }

        $job->{'user'}        = $rec{'n'};
        $job->{'printer'}     = $rec{'P'};
        $job->{'client_host'} = $rec{'H'};
        $job->{'size'}        = $rec{'b'};
        $job->{'duration'}    = $time - $job->{'time'};

        $process->write_dlf( 'print', $job);
        delete $self->{'cache'}{$jobid};
    } else {
        $process->error( 'unknown entry type', $line );
    }
}

sub finish_conversion {
    my ( $self, $process ) = @_;

    foreach my $dlf ( sort { $a->{'time'} <=> $b->{'time'} }
                      values %{$self->{'cache'}} )
    {
        $process->write_dlf( 'print', $dlf );
        delete $self->{'cache'}{ $dlf->{'job-id'} };
    }
    return;
}

1;
