package Reader::DisplayHistory;

#
# Read display.history files. Accepts arguments
#
#   directory="some directory"  [default: var]
#   base="some filename"	[default: display.history]
#   prefix="some prefix"	[default: no prefix]
#
# where directory is the directory where this reader will
# try to find files named base.*
#

use strict;

@Reader::DisplayHistory::ISA = qw( Reader::Reader );
use StatusLog;
use FileHandle;


sub new {
    my( $this ) = @_;
    my $class = ref($this) || $this;
    my $self = {};
    bless( $self, $class );
    return $self;
}



sub read {
    my( $self ) = @_;
    my $log = new StatusLog();
    my $fh = new FileHandle();
    my %status = ();

    my $prefix = ($self->get_argument("prefix"))?($self->get_argument("prefix")):"";
    my $start = $self->get_argument( "start" );
    my $end = $self->get_argument( "end" );

    my $former = Reader::Reader::create( "StatusDB", {
	"start" => $start - 22*3600
    } ) -> read();
    $former->sort();
    foreach my $item ($former->get_items()) {
	next unless( $item =~ /^history:/ );
	my $statuslist = $former->get( $item );
	my $status = $statuslist->[$#{$statuslist}];
	$status{$item} = {
	    "time" => $start,
	    "color" => $status->{"status"},
	    "comment" => $status->{"comment"}
	}
    }

    my @files = $self->find_files();
    die "no valid display history files available" if( $#files < 0 );
    open( $fh, "<".($files[0]->{"file"}) ) || die "cannot open file ".($files[0]->{"file"}).": $!";
    while( @files ) {
	$_ = <$fh>;
	s/\r//;
	unless( $_ ) {
	    close $fh;
	    shift @files;
	    last unless @files;
	    open( $fh, "<".($files[0]->{"file"}) ) || die "cannot open file ".($files[0]->{"file"}).": $!";
	    next;
	}
	chomp;
	next unless( /^([^\s\t]+\.[a-zA-Z0-9]+): ([a-z]+)->([a-z]+) \((\d+)\) (.*)$/ );
	my( $item, $colorfrom, $colorto, $time, $comment ) = ($1,$2,$3,$4,$5);
	$colorfrom = _color( $colorfrom );
	$colorto = _color( $colorto );
	$item = "history:".$prefix.$item;
	$comment = substr( $comment, 0, 60 );

	if( $time < $start ) {
	    $status{$item} = { 
		"color" => $colorto,
		"comment" => $comment,
		"time" => $start
	    };
	    next;
	}

	last if( $time > $end + 3*3600 );
	if( $time > $end ) {
	    next unless( defined $status{$item} );
	    $time = $end;
	}

	unless( defined $status{$item} ) {
	    $status{$item} = {
		"color" => $colorfrom,
		"comment" => "",
		"time" => $start
	    };
	}

	my $status = $status{$item};
	if( $status->{"color"} ne $colorfrom ) {
	    print STDERR "gap in history file ".($files[0]->{"file"}).": line number $.\n";
	}
	$log->push( $item, {
	    "item" => $item,
	    "start" => $status->{"time"},
	    "end" => $time,
	    "status" => $colorfrom,
	    "comment" => $status->{"comment"}
	} );
	if( $time < $end ) {
	    $status{$item} = {
		"color" => $colorto,
		"comment" => $comment,
		"time" => $time
	    };
	}
	else {
	    delete $status{$item};
	}
    }
    close $fh;

    my( $item, $status );
    while( ($item,$status) = each %status ) {
	$log->push( $item, {
	    "item" => $item,
	    "start" => $status->{"time"},
	    "end" => $end,
	    "status" => $status->{"color"},
	    "comment" => $status->{"comment"}
	} );
    }
    return $log;
}


sub _color {
    my( $color ) = @_;
    return $color;
}


sub find_files {
    my( $self ) = @_;
    return( @{$self->{"files"}} ) if( $self->{"files"} );
    my @files = ();
    my $fh = new FileHandle();
    my $dp = new FileHandle();
    my $dir = "$BigSister::common::fs{'var'}";
    $dir = $self->get_argument( "directory" ) if( $self->get_argument( "directory" ) ); 
    my $base = "display.history";
    $base = $self->get_argument( "base" ) if( $self->get_argument( "base" ) );

    opendir( $fh, $dir ) || die "cannot find display history: $!";
    foreach my $file (readdir( $fh )) {
	next unless( $file =~ /^\Q$base\E([\.\d]*)$/ );
	open( $dp, "<$dir/$file" ) || die "cannot open display history: $!";
	$_ = <$dp>;
	close $dp;
	unless( /.*?\((\d+)\)/ ) {
	    print STDERR "WARNING: display history file $file is unreadable/invalid - ignoring\n";
	    next;
	}
	push( @files, {
	    "file" => "$dir/$file",
	    "start" => $1
	} );
    }
    closedir( $fh );

    my @sorted = sort { $a->{"start"} <=> $b->{"start"} } @files;
    $self->{"files"} = \@sorted;
    return $self->find_files();
}


1;
