#!/usr/bin/perl

use Connect;

$dbh = database_open();

$dl_sql="select languages.value,url,saveto from pack_downloads,languages where languages.id=lang_id and pack_id=?";
$dl_h=$dbh->prepare($dl_sql);
$chk_sql="select chklevel,prnlevel,pack_chklogic.value,pack_chktype.value,pack_chkconditions.value,path,pack_checks.value from " .
         "pack_checks left join pack_chktype on (pack_checks.chktype_id=pack_chktype.id) left join pack_chklogic on " .
         "(pack_checks.chklog_id=pack_chklogic.id) left join pack_chkconditions on (pack_checks.chkcond_id=pack_chkconditions.id) " .
         "where pack_id=? order by chklog_id desc,chktype_id";
$chk_h=$dbh->prepare($chk_sql);

$cmd_sql="select pack_cmds.id,pack_cmdtype.value as cmdtype,priority,cmd,timeout from pack_cmds,pack_cmdtype where pack_id=? and " .
         "pack_cmds.cmdtype_id=pack_cmdtype.id order by cmdtype,priority";
$cmd_h=$dbh->prepare($cmd_sql);

$exits_sql="select exitcode,action_id from pack_cmdexits where cmd_id=? order by exitcode";
$exits_h=$dbh->prepare($exits_sql);

$extras_sql="select pack_exttype.value,packages.idtxt from packages,pack_extras,pack_exttype where " .
            "pack_id=? and pack_extras.exttype_id=pack_exttype.id and packages.id=pack_extras.value order by pack_exttype.value,pack_extras.priority";
$extras_h=$dbh->prepare($extras_sql);

$sql="select * from packages where obsolete!=1";
if($ARGV[0]) {
  $sql.=" and idtxt='" . $ARGV[0] . "'";
}
$sql_h=$dbh->prepare($sql);
$sql_h->execute() or die($sql . " --- " . $DBI::errstr);

@tf=( 'false', 'true' );
print "<?xml version=\"1.0\"?>\n";
print "<packages>\n\n";
while(my @pack_data=$sql_h->fetchrow_array) {
  escape_str(\@pack_data);
  print "<package id='" . $pack_data[4] . "' name='" . $pack_data[1] . "' revision='" . $pack_data[2] .
        "' priority='" . $pack_data[6] . "' reboot='" . $tf[$pack_data[5]] . "'";
  if($pack_data[7]) {
    print " execute='once'";
  }
  print " >\n";
  print "  <!-- " . $pack_data[8] . " -->\n" if ($pack_data[8]);
  print_downloads($pack_data[0]);
  $depth=-1;
  $sql2="select * from pack_checks where chklog_id is NOT NULL and pack_id=" . $pack_data[0] . " order by chklevel,chktype_id";
  $sql2_h=$dbh->prepare($sql2);
  $sql2_h->execute();

  %levels=();
  while(@level_data=$sql2_h->fetchrow_array) {
    $levels{$level_data[3]}=[ @level_data ];
  }
  print_checks($pack_data[0],0);

  print_cmds($pack_data[0]);
  print_extras($pack_data[0]);
  print "</package>\n\n";
}
print "</packages>\n";

sub escape_str {
  my ($data_ref)=@_;
  foreach $pos ( 0..$#$data_ref ) {
    $$data_ref[$pos] =~ s/\'/\"/g;
    $$data_ref[$pos] =~ s/\&/\&amp;/g;
  }
}

sub print_downloads {
  my ($pack_id)=@_;
  $dl_h->execute($pack_id) or die($dl_sql . " --- " . $DBI::errstr);
  while(my @dl_data=$dl_h->fetchrow_array) {
    $dl_data[1] =~ s/\&/%26/g;
    escape_str(\@dl_data);
    print "  <download lang='" . $dl_data[0] . "' url='" . $dl_data[1] . "' saveto='" . $dl_data[2] . "' />\n";
  }
}

sub print_cmds {
  my ($pack_id)=@_;
  $cmd_h->execute($pack_id) or die($cmd_sql . " --- " . $DBI::errstr);
  while(my @cmd_data=$cmd_h->fetchrow_array) {
    escape_str(\@cmd_data);
    print "  <" . $cmd_data[1] . " cmd='" . $cmd_data[3] . "' timeout='" . $cmd_data[4] . "' ";
    my $exit_data=print_cmdexits($cmd_data[0]);
    if($exit_data) {
      print ">\n" . $exit_data . "  </" . $cmd_data[1] .">\n";
    } else {
      print "/>\n";
    }
  }
}

sub print_extras {
  my ($pack_id)=@_;
  $extras_h->execute($pack_id) or die($extras_sql . " --- " . $DBI::errstr);
  while(my @extras_data=$extras_h->fetchrow_array) {
    escape_str(\@extras_data);
    print "  <" . $extras_data[0] . " package-id='" . $extras_data[1] . "' />\n";
  }
}

sub print_cmdexits {
  my ($cmd_id)=@_;
  my $ret_data='';
  $exits_h->execute($cmd_id) or die($exits_sql . " --- " . $DBI::errstr);
  while(my @exits_data=$exits_h->fetchrow_array) {
    escape_str(\@exits_data);
    $ret_data.="    <exit code='" . $exits_data[0] . "'";
    if($exits_data[1]>1) {
      $ret_data.=" reboot='true'";
    }
    $ret_data.=" />\n";
  }
  return $ret_data;
}


sub print_checks {
  #     0        1        2       3          4         5    6
  # chklevel,prnlevel,chklogic,chktype,chkconditions,path,value
  my $pack_id=shift @_;
  my $level=shift @_;

  my $printed_levels=();
  if($#_>=1) {
    $prnlevel=shift @_;
    $level_id=shift @_;
  }
  $depth++;
  $sql3="select count(id) from pack_checks where pack_id='" . $pack_id . "'";
  $sql3_h=$dbh->prepare($sql3);
  $sql3_h->execute() or die($sql3 . " --- " . $DBI::errstr);
  ($chk_count)=$sql3_h->fetchrow_array;
  $chk_h->execute($pack_id) or die($chk_sql . " --- " . $DBI::errstr);
  $count=0;
  while(my @chk_data=$chk_h->fetchrow_array) {
    $count++;
    if($chk_data[1]!='') {
      print "  <check type='logical' condition='" . $chk_data[2] . "'>\n" if ( $chk_count>2 );
      next;
    }
    for($i=0;$i<$level;$i++) {
      print "  ";
    }
    print "  <check type='" . $chk_data[3] . "' condition='" . $chk_data[4] . "' path='" . $chk_data[5] . "'";
    if($chk_data[6]) {
      print " value='" . $chk_data[6] . "'";
    }
    print " />\n";
  }
  if(defined($levels[$level])) {
    foreach $nextlevel ( $levels[$level] ) {
      if(!defined($printed_levels[$nextlevel[0]])) {
        print_checks($pack_id,$nextlevel[2],$level,$nextlevel[0]);
        $printed_levels[$nextlevel[0]]=1;
      }
    }
  }
  print "  </check>\n" if ($count>0 && $chk_count>2);
}
