##############################################################################################
# © Copyright 2000-2007 Hewlett-Packard Development Company, L.P
#
# 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.
#
# You should have received a copy of the GNU General Public License along with this program; 
# if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##############################################################################################
# Create a logfile so we can help troubleshoot errors
my $log = "/var/log/LinuxCOE-base.log";
open(LOG,">$log") ||  print STDERR "Cannot open $log : $!\n What's up with that? :)\n\n";

# Make everything hot, I'm forking...
select(LOG); $|=1;
select(STDOUT); $|=1;
select(STDERR); $|=1;

print LOG "Scroll down to ===START=== for the real action.\n";

# Load an %array of installed rpms....
my %installed = &load_installed;

# this %array created by /systemdesigner-cgi-bin/nph-debian_image
my %bundles = (

# REAL_DATA_HERE

);

# Snatch the waystation they selected
#  note to self: do not name a valid bundle 'WaYsTaTiOn' ;p

my $waystation = $bundles{'WaYsTaTiOn'};
delete($bundles{'WaYsTaTiOn'}); # let's not load this one!

unless ( -d "/etc/opt/LinuxCOE" ) { system "/bin/mkdir -p /etc/opt/LinuxCOE" }
open(WAY,">/etc/opt/LinuxCOE/waystation");
print WAY "$waystation\n";
close(WAY);

print LOG " ===START=== \n";
print LOG "My Waystation is $waystation\n";

#
# main()  - here's the meat!
#

# Walk the default rpms that are configured and install

print "\nLinuxCOE 3.1 post installation processing\n\n";
foreach $bundle (sort(keys(%bundles))) {
  &load_bundle($bundle,$bundles{$bundle},$waystation);
}
if ( -x "/opt/LinuxCOE/bin/install_bundles" ) {
  print "\n\n";
  system "/opt/LinuxCOE/bin/install_bundles INSTALL";
}
print STDERR "Done!  Thanks for choosing LinuxCOE!\n";

system "/usr/bin/chvt 1";
#
# End of main() - the rest is gravy...
#

sub load_bundle {

# Cycle through rpms associated with this bundle, load as needed.

  my ($bundle,$files,$waystation) = @_;
  print LOG "Installing $bundle bundle from $waystation\n";
  print STDERR "Installing $bundle bundle from $waystation - ";
  my $test = $bundle;
  my $step = chop($test);
  system "/bin/echo -n 'Initial processing step $step of 3                                       '";
  my @needem;
  my @rpms = split(' ',$files);

# Foreach rpm, see if it's needed
  foreach $rpm (@rpms) {
    if ( &need_it($rpm) ) { 
      print LOG " will install\n";
      push(@needem,$rpm); 
    } else {
      print LOG " already got it\n";
    }
  }

# Do we need any?  If so, attempt to install them
  if (@needem) {
    my $line = join(" ",@needem);
    &load_debs($bundle,$line); 
  } else {
    print LOG "$bundle is installed or superseded...\n";
    print STDERR "already got it, continuing...\n";
  }

}

sub need_it {

# is the rpm passed needed?

  my $rpm = shift;
  # Rip off all the leading path cruft;
  my @data = split('/',$rpm);
  $rpm = pop(@data);        # grab the rpm name sans path
  (@data) = split('\.',$rpm);
  pop(@data); pop(@data);   # Get rid of .arch.deb
  my ($name,$ver) = &parse_deb(join('.',@data));
  print LOG "$name, comparing new $ver to installed $installed{$name}";
  if (( $ver gt $installed{$name} ) || ( ! $installed{$name} )) { return(1) }  # we need it!
  return;  # they got it!

}

sub parse_deb {

# ii  xlibs-data                 4.3.0.dfsg.1-8             X Window System client data

  my $data = shift(@_);
  if ( $data =~ /^ii / ) {
    my ($ii,$test,$ver,@rest) = split(' ',$data);
    return($test,$ver);
  } else {
    my @arr = split('-',$data);
    my ($test,@p);
    while ( $test = shift(@arr) ) {
      last if ( $test =~ /^[0-9]/ );
      push(@p,$test);
    }
    return(join('-',@p),join('-',$test,@arr));
  }

}

sub load_installed {

# Create the %array of installed rpms.

 my %installed;
  open(IN,"/usr/bin/dpkg -l |") ||
    die "Cannot fork dpkg : $!\n";
  while(<IN>) {
    next unless /^ii/;
    chomp;
    my ($product,$rev) = &parse_deb($_);
    $installed{$product} = $rev;
    print LOG "Found installed product $product - $rev\n";
  }
  return(%installed);

}

sub make_snippet {

# Create a /etc/rc.d/init.d snippet to try again next reboot  # BUG!

  ($bundle,$debs) = @_;
  my @debnames;
  my @deblist = split(' ',$debs);
  chdir "/tmp";
  open(RC,">/etc/init.d/LinuxCOE-$bundle");
  print RC "#!/bin/sh\ncd /tmp\n";
  foreach my $url (@deblist) {

# Fetch each deb locally

    my @data = split("/",$url);
    $debnames .= pop(@data) . " ";
    print RC qq[/usr/bin/wget $url\n];
  }
  print RC qq{/usr/bin/dpkg -i $debnames
if [ \$? -eq 0 ]
then
  /bin/rm /etc/rc*.d/*LinuxCOE-$bundle
  /bin/rm /etc/init.d/LinuxCOE-$bundle
  [ -x /etc/init.d/LinuxCOE-Bundles ] && /etc/init.d/LinuxCOE-Bundles start
else
  /bin/rm $debnames
fi
};
system "/bin/chmod +x /etc/init.d/LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/rc2.d/S99LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/rc3.d/S99LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/rc4.d/S99LinuxCOE-$bundle";
system "/bin/ln -s /etc/init.d/LinuxCOE-$bundle /etc/rc5.d/S99LinuxCOE-$bundle";

}

sub load_debs {

# Attempt to install the debs passed via HTTP

  my ($bundle,$line) = @_;
  my @urls = split(' ',$line);
  my $debs;
  foreach $url (@urls) {
    system "/usr/bin/wget $url";        # Fetch the debs
    my @data = split('/',$url);
    my $deb = pop(@data);   # grab the filename
    $debs .= " $deb";
  }  
  my $syscall = "/usr/bin/dpkg -i $debs >>${log}.dpkglog 2>&1";
  print LOG "Installing $bundle with:\n ";
  print LOG "$syscall";
  system $syscall;
  if ( $? != 0 ) {
    print LOG " $bundle failed, making rc.d snippet, will retry on next boot.\n";
    &make_snippet($bundle,$line,$debs);
    print STDERR " failed \n";
    print "  [Failed]\n";
  } else {
    print STDERR " ok!\n";
    print " [OK]\n";
  }
  system "/bin/rm $debs";		# Remove the files

}
