#
# Copyright (c) 1990,1991,1992 The Ohio State University.
# All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that: (1) source distributions retain this entire copyright
# notice and comment, and (2) distributions including binaries display
# the following acknowledgement:  ``This product includes software
# developed by The Ohio State University and its contributors''
# in the documentation or other materials provided with the distribution
# and in all advertising materials mentioning features or use of this
# software. Neither the name of the University nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#

#
# 2.5convert
#

$usage = "usage: 2.5convert [-d debuglevel]\n";
$options = "d:";

require 'global.defs';
require 'local.defs';
require $yagrip_perl;
require $backuplib_perl;

&read_config();			# Read backup.config file
				#     (need config_name)
&init();			# Deal with args and get necessary info...

dbmopen(TAPEDB, $tape_db_file, $db_mode);

&tape_type_phase();

&tape_id_phase();

&backup_update_phase();

dbmclose(TAPEDB);

exit(0);


sub init {
    $SIG{'INT'} = 'handle_interrupts';
    $SIG{'HUP'} = 'handle_interrupts';

    die $usage if ! &getopt($options);
    die $usage if $#ARGV != -1;
    die $usage if defined($opt_h);

    if (! chdir $db_dir) {
	die "cannot chdir to $db_dir\n";
    }
}


sub tape_type_phase {
    local($cmd);

    print "Adding tape types and formats\n";

  cmd_loop: 
    while (1) {
	&summarize_types();

	$cmd = &askdef("tape type command ", "", 
"Enter a command for changing tape types.  Valid commands are:
	<num>	        to change the type for tape <num>
	<num>-<num>	to change the type for tapes <num>-<num>
	l		to list the tapes and their types
	u		to list the tapes that do not have types yet
	q		to quit 
Note that you can ^C from this whenever you want.\n");

      choices: {
	  if ($cmd =~ m/^([0-9]+)$/) {
	      &change_type($1 + 0, $1 + 0);
	      last choices;
	  }

	  if ($cmd =~ m/^([0-9]+)-([0-9]+)$/) {
	      &change_type($1 + 0, $2 + 0);
	      last choices;
	  }

	  if ($cmd eq "l") {
	      &list_types();
	      last choices;
	  }

	  if ($cmd eq "u") {
	      &list_untyped();
	      last choices;
	  }

	  if ($cmd eq "q") {
	      if (&summarize_types()) {
		  print "Sorry, there are still some tapes that do not have types.\nYou can't proceed to the next phase until you give types to all of the tapes.\n";
		  last choices;
	      } else {
		  last cmd_loop;
	      }
	  }

	  print stderr "Bogus command.\n";
      }
    }
}


sub summarize_types {
    local($key, $value, $min, $max, $untyped, $total);
    local(%tape);

    print "summarize tape types\n" if $opt_d & $DEBUG_INFO;

    $min = 100000;
    $max = -1;
    $total = 0; $untyped = 0;

    while (($key, $value) = each %TAPEDB) {
	if (! defined($value) || $value eq "") {
	    print "tape $key doesn't have a value in the database, deleting...\n";
	    delete $TAPEDB{$key};
	    next;
	}

	&parse_db_entry($value, *tape);

	$key += 0;

	$max = $key if ($key > $max);
	$min = $key if ($key < $min);

	$total++;
	if (! defined($tape{"type"}) || $tape{"type"} eq "") {
	    $untyped++;
	}
    }

    print "$total tapes, $untyped without types.  Min ID is $min, max is $max\n";

    return $untyped;
}

sub change_type {
    local($n, $m) = @_;
    local($type, $format, $key, %tape);

    $type = &askdef("Type ", "exb", "Give the tape type that you want to assign to these tapes.\n");
    $format = &askdef("Format ", "8200", "Give the tape format that you want to assign to these tapes.\n");

    foreach $key (keys %TAPEDB) {
	$num = $key + 0;

	if ($num < $n || $num > $m) {
	    next;
	}

	print "Deal with tape $key\n" if $opt_d & $DEBUG_INFO;

	&parse_db_entry($TAPEDB{$key}, *tape);

	$tape{"type"} = $type;
	$tape{"format"} = $format;

	$TAPEDB{$key} = &pack_em_up(%tape);
    }
}

sub list_types {
    local($key, $value);
    local(%tape);

    print "List tape types\n" if $opt_d & $DEBUG_INFO;

    foreach $key (sort increasing keys %TAPEDB) {
	if (! defined($TAPEDB{$key}) || $TAPEDB{$key} eq "") {
	    print "tape $key doesn't have a value in the database, deleting...\n";
	    delete $TAPEDB{$key};
	    next;
	}

	&parse_db_entry($TAPEDB{$key}, *tape);

	printf "$key\t%s\t%s\n", $tape{"type"}, $tape{"format"};
    }
}

sub list_untyped {
    local($key, $value);
    local(%tape);

    print "List tapes with no types\n" if $opt_d & $DEBUG_INFO;

    foreach $key (sort increasing keys %TAPEDB) {
	if (! defined($TAPEDB{$key}) || $TAPEDB{$key} eq "") {
	    print "tape $key doesn't have a value in the database, deleting...\n";
	    delete $TAPEDB{$key};
	    next;
	}

	&parse_db_entry($TAPEDB{$key}, *tape);

	if (! defined($tape{"type"}) || $tape{"type"} eq "" ||
	    ! defined($tape{"format"}) || $tape{"format"} eq "") {
	    printf "$key\t%s\t%s\n", $tape{"type"}, $tape{"format"};
	} else {
	    printf "skipping $key\t%s\t%s\n", $tape{"type"}, $tape{"format"}
	      if $opt_d & $DEBUG_INFO;
	}
    }
}

sub tape_id_phase {
    local(@old_list, $old, $new, %tape);

    print "Change Tape IDs Phase\n";
    &askdef("Return to continue", "", "");

    @old_list = keys %TAPEDB;

    foreach $old (@old_list) {
	&parse_db_entry($TAPEDB{$old}, *tape);

	if ($old =~ m/-([0-9]+)$/) {
	    $num = $1;
	} else {
	    $num = $old;
	}

	$tape_type_cache{$num+0} = $tape{"type"};

	$new = &make_tape_id_from_number($tape{"type"}, $num+0);
	$TAPEDB{$new} = $TAPEDB{$old};

	print "  changing $old into $new\n";
    }

    foreach $old (@old_list) {
	print "  deleting $old\n";
	delete $TAPEDB{$old};
    }
}

sub backup_update_phase {
    local($pattern, $name, @tmp, %DB, %entry, $key);

    print "Backup Database Update Phase\n";
    &askdef("Return to continue", "", "");

    $pattern = "$backup_host_file*.$dbext";
    foreach $name (<${pattern}>) {
	@tmp = split(/\./, $name);
        pop(@tmp);			# nuke trailing .$dbext
        $name = join('.', @tmp);

	print "  Working on $name\n";

        dbmopen(DB, $name, $db_mode);

	foreach $key (keys %DB) {
	    %entry = ();
	    &parse_db_entry($DB{$key}, *entry);

	    if (defined($entry{"tflist"})) {
		$old = $entry{"tflist"};

		@tflist = split(/,/, $entry{"tflist"});
	      tf_loop:
		for ($i = 0; $i <= $#tflist; $i++) {
		    ($tape, $file) = split(/\./, $tflist[$i]);
		    if ($tape =~ m/-([0-9]+)$/) {
			$tape = $1;
		    }

		    if (! defined($tape_type_cache{$tape+0})) {
			print stderr "unknown tape ID $tape - skipping tflist entry in backup $key in $name\n";
			next tf_loop;
		    }

		    $tape = &make_tape_id_from_number($tape_type_cache{$tape+0}, $tape+0);
		    $tflist[$i] = join('.', $tape, $file);
		}
		$entry{"tflist"} = join(',', @tflist);

		printf "    buid  $key\told: %s\tnew: %s\n",
			$old,
			$entry{"tflist"};

		$DB{$key} = &pack_em_up(%entry);
	    }
	}

	dbmclose(DB);
    }
}
