#! /usr/bin/perl

#*********************************************************************
#
# fai-monitor-gui: graphical FAI monitor daemon
#
# This script is part of FAI (Fully Automatic Installation)
# Copyright (C) 2007-2012 Thomas Lange, lange@informatik.uni-koeln.de
# Universitaet zu Koeln
#
#*********************************************************************
# This program 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.
#
# A copy of the GNU General Public License is available as
# '/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html.  You
# can also obtain it by writing to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#*********************************************************************

# TODO: Add support for TASKERROR

use strict;
use Getopt::Std;
use Tk;
use Tk::HList;
use Tk::ItemStyle;
#use Tk::Balloon;

my $tcounter;
my $n;
our ($opt_s,$font1,$font2,$icondir,$top,$defstyle,$hlist,$backcolor,$forecolor,$headercolor,$headerstyle,$input);
our(%icon,%task,%row);

my $debug = 0;

#@tasklist = qw/hostname confdir defclass action partition mountdisks extrbase debconf repository instsoft configure chboot savelog faiend reboot/;
my @tasklist = qw/hostname confdir defclass partition extrbase repository instsoft configure tests savelog faiend reboot/;
$tasklist[0] = ' 'x15 . 'hostname'. ' 'x15;


my $rowcount = 0;
my %message = ( 'TASKBEGIN' => 'BEG', 'TASKEND' => 'END');

# -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
sub getinp {

  my $line = <$input>;
  return 0 if $line =~/^FAI monitoring daemon start/; # ignore start up messages from fai-monitor
  return 0 if $line =~/Disabling pxelinux configuration/;
  warn "INPUT received $line" if $debug;
  hostentry($line);
  return 0;
}
# -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
sub mkgraphics {

  #Style entries

  $icon{'success'} = $top->Photo(-file=>"$icondir/ok.gif");
  $icon{'minor'}   = $top->Photo(-file=>"$icondir/minor.gif");
  $icon{'warning'} = $top->Photo(-file=>"$icondir/warning.gif");
  $icon{'fail'}    = $top->Photo(-file=>"$icondir/fail.gif");
  $icon{'begin'}   = $top->Photo(-file=>"$icondir/begin.gif");
  $icon{'host'}    = $top->Photo(-file=>"$icondir/bar.gif");

  $defstyle = $hlist->ItemStyle("imagetext",
                                -foreground => $forecolor,
                                -background => $backcolor,
                                -font => $font2,
                               );

  $headerstyle = $hlist->ItemStyle("imagetext",
                                   -bg=>$backcolor,
                                   -fg=>$headercolor,
                                   -font=>$font1
                                  );

  # not yet used
  # $balloonstatus = $top->Balloon();
  # $balloonstatus->attach($top,-msg=>"status",-balloonposition=>"mouse");
}
# -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
sub icon {

    my ($host,$task,$iname) = @_;

    $hlist->itemCreate($row{$host}, $task{$task}, -text=>'' ,-itemtype=>"imagetext",-image=>$icon{$iname});
    $hlist->itemConfigure($row{$host}, $task{$task}, -itemtype=>"imagetext",-style=>$defstyle);
}
# -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
sub hostentry {

  my $str = shift(@_);
  my ($host,$startstop,$task,$code) = split(/\s+/,$str);
  my $message;

  warn "hostentry: $host $startstop $task $code\n" if $debug;

  unless (exists $row{$host}) {
    # add host, first column
    $row{$host} = $rowcount++;

    $hlist->add($row{$host},-state=>"disabled");
    $hlist->itemCreate($row{$host}, 0,
                       -itemtype => "imagetext",
                       -text => $host,
                       -style=>$headerstyle,
                       -image=>$icon{'host'});
  }

  # remove old information when doing an reinstallation
  if ($startstop eq 'check') {
    foreach (1 .. $#tasklist) {
      warn "row: $row{$host} nr.:  $_\n" if $debug;
      $hlist->itemCreate($row{$host}, $_, -text => '');
    }
    return;
  }

  warn "create: $row{$host} | $task{$task} | $startstop $message{$startstop} $code\n" if $debug;
  unless (exists $task{$task}) {
    # do not show unknown tasks
    return;
  }

  $message = ($startstop =~ /TASKEND/) ?  $message="$message{$startstop} $code": $message{$startstop};

  ($message eq 'BEG')   && icon($host,$task,'begin');
  if ($message =~ /END (\d+)/) {
    my $ret = $1; # save error code
    ($ret < 300) and icon($host,$task,'success'),return;
    ($ret < 500) and icon($host,$task,'warning'),return;
    ($ret < 700) and icon($host,$task,'minor'),return;
    icon($host,$task,'fail');
  }

}
# -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
sub usage {

  print << "EOF";
fai-monitor-gui, graphical FAI monitor daemon

   Copyright (C) 2007-2012 by Thomas Lange

Usage: fai-monitor | fai-monitor-gui -

   -s                   Use smaller icons.

EOF
  exit 0;
}
# -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
# main program

# check for old script name
my $callname;
$callname = $0;
$callname =~ s#.+/##;
if ($callname eq 'faimond-gui') {
  warn "WARNING: faimond is now called fai-monitor-gui.\n";
  warn "In the future only fai-monitor will be available.\n";
}

getopts('s') || usage;

if ($opt_s) {
  $font1="Sans 13";
  $font2="Sans 7";
  $icondir='/usr/share/fai/pixmaps/small';
} else {
  $font1="Sans 15";
  $font2="Sans 10";
  $icondir='/usr/share/fai/pixmaps';
}

$backcolor="#76716f";
$forecolor="#ffffff";
$headercolor="#ffffff";

open($input, "<$ARGV[0]") or die "Can't open input file. $@";

$top = new MainWindow;
#$top->configure(-background=> $backcolor);
$hlist = $top->Scrolled("HList",
            -header => 1,
            -font => $font2,
            -columns => $#tasklist+1,
            -scrollbars => 'oe',
            -width => 102,
            -height => 20,
            -selectbackground => $backcolor,
            -background=> $backcolor,
            -selectborderwidth=>0,
            -selectmode=>'single',
            -highlightthickness=>0,
            -relief=>'flat',
            -borderwidth=>0,
         )->pack(-expand => 1, -fill => 'both');

mkgraphics;
$top->fileevent($input,'readable', [\&getinp]);

foreach (@tasklist) {
  $hlist->header('create', $n++, -text => $_,
                 -headerbackground=>"#aabbcc",
                 -borderwidth=>1,
                 -relief=>"groove");
  $task{$_} = $tcounter++;
}

MainLoop();
