#!/usr/bin/perl
# Copyright Peter Jordan 2001
# Licensed under GPL
# Permission granted to distribute, use and modify provided this notice is retained.

use strict;
use CGI;
#use File::stat;
#use Fnctl ':mode';


my $tftpdir = "TFTPROOT";
my $subnet = "NETWORK-SHORT";
my $bootlink = "bootme";
my $yaboot = "yaboot.conf";

my $query=new CGI;


# get allowed choices for the second stage loader, prepend MacOS as first stage choice
my %nextboots;
$nextboots{"MacOS"} = ();
opendir(DIR, $tftpdir) || die("can't opendir $tftpdir: $!");
# assumes policy, that yaboot.conf symlinks are to be ignored as choices, in particular the yaboot.conf-postinst
grep { m{^$yaboot-(\w+)$} && ($nextboots{$1} = ()); } grep { -f ("$tftpdir/$_") && ! -l ("$tftpdir/$_"); } readdir(DIR);

#grep grep { ($nextboots{m{^$yaboot-(\w+)$} && ($nextboots{$1} = ()) && (-f $_); } readdir(DIR);
closedir DIR;

# TODO - redo this so we just take existing bootdirs and check those values - see below - umm. but for groups ?
# make the links. this is the workhorse


my %returns=$query->Vars;
for my $bootdir ( grep { /$subnet\.\d+/ } keys %returns) { # filter for the IP named boot dirs only
  # oh what an ugly but quick hack to make the setallto work
  if (exists $nextboots{$query->param('setallto')}) {
    $returns{$bootdir} = $query->param('setallto') }   

  if ($returns{$bootdir} =~ /MacOS/) {
    # hey. uhhh.. what file are ya deleting.. 
    unlink("$tftpdir/$bootdir/$bootlink");
    symlink("../bootmacos","$tftpdir/$bootdir/$bootlink") || die("symlink $tftpdir/$bootdir/$bootlink: $!");
  }
  else {
    unlink("$tftpdir/$bootdir/$bootlink");
    symlink("../bootlinux","$tftpdir/$bootdir/$bootlink") || die("symlink:$!");
    unlink("$tftpdir/$bootdir/$yaboot");
    if (exists $nextboots{$returns{$bootdir}}) {
      symlink("../yaboot.conf-$returns{$bootdir}","$tftpdir/$bootdir/$yaboot") || die("symlink:$!");
    }
  } 
} # for

# get list of IP named directories in tftpdir
opendir(DIR, $tftpdir) || die("can't opendir $tftpdir: $!");
my @twistdirs = grep { /^$subnet\.\d+$/ && -d "$tftpdir/$_" } readdir(DIR);
closedir DIR;


# v-strings - convert IP address to integer rep. and sort and then convert back to IP
my @twistdirs = map {sprintf("%vd", $_)} sort map { eval "v$_" } @twistdirs;

# set up %NODE with IP:next-boot-state
my %NODE;
for my $twistdir (@twistdirs) {
  my $link = "$tftpdir/$twistdir/$bootlink";
  if (-l "$tftpdir/$twistdir/$bootlink") {
    # primary stage bootloader
    ($NODE{$twistdir}) = (readlink("$tftpdir/$twistdir/$bootlink") =~ m{^\.\.\/(\w+)$}); 
    # seconday stage bootloader
      #print "$NODE{$twistdir}\n";
    if ($NODE{$twistdir} =~ /linux/) {
      ($NODE{$twistdir}) = (readlink("$tftpdir/$twistdir/$yaboot") =~ m{^\.\.\/yaboot.conf-(\w+)$}); 
    }
    # TODO third state, task subset
    # if () {}
  } # if bootlink is a link
} # for @twistdirs



#my %saw;
#undef %saw;
#@saw{values %NODE} = ();
#my @uniqvals=keys %saw;


# this is where the html gets spit out
print $query->header;
print $query->start_html('Next Boot State');

print $query->start_form;
print $query->table(
  $query->Tr($query->th(['Host/Node', 'Next Boot', 'Change'])),
  $query->Tr([ map {my $addy = sprintf("%vd", $_);
    $query->td(
      [ $addy, qq{<IMG src="/images/$NODE{$addy}.png" alt="$NODE{$addy}">}, $query->popup_menu(
        -name=>"$addy", -values=>\%nextboots, -default=>"MacOS")
#        -name=>"BOOT-$addy", -values=>\@uniqvals)
      ]
    )} sort map { eval "v$_" } keys %NODE
  ]));

print $query->p;
print $query->submit(-name=>".submit", -value=>"Apply Changes");
print $query->p;

print $query->table({-border=>"2"},
  $query->Tr($query->th(['Set All to:'])),
  $query->Tr([ map { $query->td($query->submit(-name=>"setallto", -value=>"$_")) }  keys %nextboots ]));

print $query->end_form;

print $query->end_html;

# set all, set one
