package Catalog::Grid;
use Catalog::RF;
use base 'Catalog::RF';
use strict;

###################################################
# GFRID FILES
#
# Event Grid parsing
# Author: Christian Cadieux
#   
# Grid        : System/EGrid/*grid
#               $grid= Catalog::Grid->parseFile("System/EGrid/t3.grid");
#               print $grid->toText();
# <grid>
# <event name="t3.ValueChangeEvent.disk.Glist">
#  <code>13.3.175</code>
#  <severity>E</severity>
#  <actionable>1</actionable>
#  <desc>asdsad
#  </desc>
# </event>
###################################################

sub info {
  return { ROOT => "grid",
          hash  => { event => "name" },
             };
}

sub toCatalog {
  my($class, $arg) = @_;
  my $D = System->get_home() . "/System/EGrid";
  my(%D2);
  opendir(O, $D);
  my @files = readdir(O); closedir(O);
  my $C = System->get_home() . Catalog->device_path();

  foreach my $f (sort @files) {
    if ($f =~ /(\w+)\.grid$/) {
       my $type = $1;
       my $diag = $class->parseFile("System/EGrid/$f");
       mkdir "$C/$type",0777 if (!-d "$C/$type");
       open(W, ">$C/$type/grid.xml");
       print W $diag->toXML();
       close(W);
    }
  }
}

sub fromCatalog {
  my($class, $arg) = @_;
  my $D = ($arg->{BASE_DIR} || System->get_home()) .  Catalog->device_path();
  chdir $D;
  my @files = `ls */grid.xml`;

  my $DATA =  Catalog->system_path() . "/EGrid/";
  mkdir $DATA,0777 if (!-d $DATA);

  my(%D2);
  foreach my $f (@files) {
     chomp($f);
     my $rep =  Catalog::XML->parseFile("$D/$f", $class->info());
     if (!$rep) {
         print "Error reading Catalog/device/$f\n";
         last;
     }
     my $ix = index($f, "/");
     my $f2 = substr($f, 0, $ix);
     open(W, ">$DATA/$f2.grid");
     print W $class->toText($rep);
     close(W);
  }
}



sub parseFile {
  my($class, $file, $arg) = @_;

  my $D = System->get_home();
  if (open(O, "$D/$file")) {
     my @l = <O>; close(O);
     return $class->parse(\@l,  $class->file_name($file));
  } else {
     $class->err("opening $file: $! \n");
     return undef;
  }
}

sub parse {
  my($class, $array, $file_name) = @_;

  my $out .= "<grid file=\"$file_name\" revision=\"\$" . "Revision:\$\">\n";
  my ($key, %V, $open, $current);
  foreach my $l (@$array) {
    chomp($l);
    if (substr($l,0,1) eq "#") {
        $out .= "<!-- $l -->\n";
        next;
    }
    if (substr($l,0,1) eq "'") {
        $V{$current} .= "\n" . substr($l,1);
    } elsif (index($l, "=") > 0) {
      my($name, $val) = split(/\s*=\s*/, $l, 2);
      if ($name eq "type") {
        $key = $val;
        if ($current) {
          $out .= &add_event(\%V);
          $open--;
          $out .= "\n";
        }
        $out .= "<event name=\"$val\">\n";
        $open++;
        %V = ();
      } else {
        $V{$name} .= $val;
        $current = $name;
      }
    }
  }
  $out .= &add_event(\%V);
  $out .= "</grid>";
  my $report =  Catalog::XML->parse($out, $class->info());
  bless($report, "Catalog::Grid");
  return $report;
}

sub add_event {
  my($V) = @_;
  my $out;
  foreach my $el ('code','severity','actionable') {
      $out .= "  <$el>$V->{$el}</$el>\n";
  }
  foreach my $el ('desc','info','cause','action') {
      if (exists $V->{$el}) {
         my $v = $V->{$el};
         $v =~ s/</[/g;
         $v =~ s/>/]/g;
         $out .= "  <$el>$v</$el>\n";
       }
   }
   $out .= " </event>\n";
   return $out;
}


sub toText {
  my($class, $grid) = @_;
  $grid = $class if (ref($class));
  my $out;
  my $report = $grid->{grid}{event};
  foreach my $ev (sort keys %$report) {
    next if (substr($ev,0,1) eq "_");
    $out .= "\ntype=$ev\n";
    my $v = $report->{$ev};
    my @L = ('code','severity','actionable','desc');
    foreach my $el (sort keys %$v) {
       push(@L, $el) if (index(",code,severity,actionable,desc,", ",$el,") < 0);
    }
    foreach my $el (@L) {
       next if ($el eq "type" || substr($el,0,1) eq "_");
       my $val = $v->{$el}{_VAL};
       if (index(",desc,info,cause,action,", ",$el,") >= 0) {
         $val =~ s/\n/\n'/g;
       }
       $out .= "$el=$val\n";
    }
  }
  return $out;
}


1;
