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


###################################################
# DIAGNOSTIC TEST FILES
#
# Diagnmostic Parsing
# Author: Christian Cadieux
# Transform back and forth between storade resource files and XML documents.

# Diag : System/Tests/
#               $test = Catalog::Diag->parseFile("System/Tests/3511.test");
#               print $text->toXML();
#               print $text->toText();

#[3510-Test]
#name=disktest
#title=disktest
#devType=3510
#manpage=disktest
#node=d
#path=disktest
#defaults=ST_defaults
#
#row1.opt=rawsub
#row1.type=radio
#row1.values=Enable|Disable
#row1.default=Enable
#row1.name=Test Media
#
#row2.opt=partition
#row2.type=select
#row2.values= 0|1|2|3|4|5|6|7
#row2.name=Partition
#row2.default=0
#
# <diagnostic>
#  <test name=3510-Test>
#    <info>
#    <name>disktest</name>
#    <devType>3510</devType>
#    <title>disktest</title>
#    <node>d</node>
#    <path>disktest</path>
#    <defaults>ST_defalts</defailt>
#   </info>
#   <parm no=1>
#     <opt>fstest</opt>
#     <type>radio</type>
#     <values>user|critical</values>
#  </parm>
#  </test>
# </diagnostic>
#
###################################################

# write to System/Catalog/Device/<device_Type>/diag.xml
# used to create the catalog

sub info {  
  return {  ROOT => "diagnostic",
           hash  => { test => "name" },
           array => { parm => 1 },
         };
}


sub toCatalog {
  my($class, $arg) = @_;
  my $D = System->get_home() . "/System/Tests";
  my(%D2);
  opendir(O, $D);
  my @files = readdir(O); closedir(O);
  foreach my $f (@files) {
    if ($f =~ /\.test$/) {
       my $diag = $class->parseFile("System/Tests/$f");
       my $tests = $diag->{diagnostic}{test};
       foreach my $name (keys %$tests) {
            next if ($name eq "_ATT");
            my $type = $tests->{$name}{info}{devType}{_VAL};
            if ($type) {
              $D2{$type}{$name} = $tests->{$name};
            } else {
              print "Error: no devType for $f:$name \n";
            }
       }
    }
  }
  my $C = System->get_home() . Catalog->device_path();
  foreach my $t (keys %D2) {
      mkdir "$C/$t",0777 if (!-d "$C/$t");
      my $d = $class->new( $D2{$t});
      open(W, ">$C/$t/diag.xml");
      print W $d->toXML();
      close(W);
  }
}

# return to original format in DATA/Catalog/Tests/<device_type>.test
#
sub fromCatalog {
  my($class, $arg) = @_;
  my $base = $arg->{BASE_DIR} ||  System->get_home();
  my $D = $base . Catalog->device_path();
  chdir $D;
  my @files = `ls */diag.xml`;

  my $DATA = Catalog->system_path() . "/Tests/";
  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.test");
     print W $class->toText($rep);
     close(W);
  }
}

sub new {
  my($class, $rep) = @_;
  my $d =  {diagnostic => {  _ATT => { revision => "\$" . "Revision:\$" },
                             test => $rep },  _ARG => $class->info()};

  bless($d, "Catalog::Diag");
  return $d;
}

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

  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 .= "<diagnostic file=\"$file_name\" revision=\"\$" . "Revision: \$\">\n";
  my (%INFO, @ROWS, $row, $test, $x);
  foreach my $l (@$array) {
    chomp($l);
    if (substr($l,0,1) eq "#") {
        $out .= "<!-- $l -->\n";
        next;
    }
    if ($l =~ /^\[(.+)\]/) {
       if ($test) {
         $out .= &diag_display(\@ROWS, \%INFO, $test);
       }
       $test= $1;
       @ROWS = (); %INFO = ();

    } elsif ($l =~ /^row(\d+)/) {
       $row = $1;
       my($name, $value) = split(/\=/, $l, 2);
       my($name0, $name1) = split(/\./, $name);
       $ROWS[$row]{$name1} = $value;
    } else {
       my($name, $value) = split(/\=/, $l, 2);
       $INFO{$name} = $value if ($value);
    }
  }
  $out .= &diag_display(\@ROWS, \%INFO, $test);
  $out .= "</diagnostic>";
  my $report = Catalog::XML->parse($out, $class->info());
  bless($report, "Catalog::Diag");
  return $report;
}


sub diag_display {
  my($ROWS, $INFO, $test) = @_;
  my($x);
  my $out = "<test name=\"$test\">\n <info>\n";
  foreach my $el (keys %$INFO) {
    $out .= "   <$el>$INFO->{$el}</$el>\n";
  }
  $out .= " </info>\n";
  for ($x=0; $x <= $#$ROWS; $x++) {
    my $vs = $ROWS->[$x];
    next if (!$vs);
    $out .= "   <parm no=\"$x\">\n";
    foreach my $el (sort keys %$vs) {
      $out .= "     <$el>$vs->{$el}</$el>\n";
    }
    $out .= "   </parm>\n";
  }
  $out .= "</test>\n";
  return $out;
}
    


# Catalog::Diag->toText($rep)
# $rep->toText

sub toText {
  my($class, $diag) = @_;

  $diag = $class if (ref($class));
  my $out;
  my $report = $diag->{diagnostic}{test};
  my($x);
  foreach my $ev (sort keys %$report) {
    next if (substr($ev,0,1) eq "_");
    $out .= "\n[$ev]\n";
    my $r = $report->{$ev};
    my $info = $r->{info};
    my $parms = $r->{parm};
    foreach my $el (sort keys %$info) {
       $out .= "$el=$info->{$el}{_VAL}\n";
    }
    for ($x=0; $x <= $#$parms; $x++) {
      my $p = $parms->[$x];
      my $row = $p->{_ATT}{no};
      if ($p) {
        $out .= "\n";
        foreach my $el (sort keys %$p) {
          next if ($el eq "_ATT");
          $out .= "row$row.$el=$p->{$el}{_VAL}\n";
        }
      }
    }
  }
  return $out;
}

1;
