#!/usr/bin/perl

use strict;

my $VYATTA_CONFIG_DIR = "/opt/vyatta/etc/config-migrate";
my $CURRENT_VERSION_DIR = "$VYATTA_CONFIG_DIR/current";
my $SAVE_DIR = "/tmp/cfg-downgrade-$$";
my $MIGRATE_SCRIPT = "/opt/vyatta/sbin/vyatta_config_migrate.pl";

sub usage {
  print <<'EOM';
Usage: config-downgrade <cfg_file> <to_version>
    <to_version>: a release name (e.g., '3.0.6') or a config version string.
EOM
  exit 1;
}

sub cleanup_save {
  system("mv $SAVE_DIR/* $CURRENT_VERSION_DIR");
  rmdir $SAVE_DIR;
}

my $GLENDALE_VERSTR = 'cluster@1:dhcp-relay@1:dhcp-server@1:firewall@2:'
                      . 'nat@2:serial@1:webgui@1';
my $HOLLYWOOD_VERSTR = 'webgui@1:wanloadbalance@1:quagga@1:cluster@1:'
                       . 'serial@1:ipsec@1:firewall@3:dhcp-relay@1:'
                       . 'dhcp-server@3:nat@2:vrrp@1';

my %ref_ver_str = (
                    '3.0.5' => "$GLENDALE_VERSTR",
                    '3.0.6' => "$GLENDALE_VERSTR",
                    'VC4.0.1' => "$GLENDALE_VERSTR",
                    'VC4.0.2' => "$GLENDALE_VERSTR",
                    '3.1.3' => "$HOLLYWOOD_VERSTR",
                    '3.1.4' => "$HOLLYWOOD_VERSTR",
                    'VC4.1.3' => "$HOLLYWOOD_VERSTR",
                    'VC4.1.4' => "$HOLLYWOOD_VERSTR",
                  );

my $cfg_file = $ARGV[0];
my $version = $ARGV[1];

if (!defined($cfg_file) || !defined($version)) {
  usage();
}

if (! -e $cfg_file) {
  print "Config \"$cfg_file\" does not exist\n";
  exit 1;
}

if (! -w $cfg_file) {
  print "Config \"$cfg_file\" is not writable\n";
  exit 1;
}

my $uid = `echo \$UID`;
if ($uid != 0) {
    print "Must be root to run this program\n";
    exit 1;
}

if (defined($ref_ver_str{$version})) {
  $version = $ref_ver_str{$version};
}

if (!($version =~ /^[-a-z]+\@\d+(:[-a-z]+\@\d+)*$/)) {
  print "Version string \"$version\" is invalid\n";
  exit 1;
}

my @ver_files = split /:/, $version;

# first save the current version files
if (!(mkdir $SAVE_DIR)) {
  print "Cannot create dir \"$SAVE_DIR\". Config not changed\n";
  exit 1;
}

system("mv $CURRENT_VERSION_DIR/* $SAVE_DIR/");
if ($? >> 8) {
  print "Error: Cannot change $CURRENT_VERSION_DIR. Config not changed\n";
  cleanup_save();
  exit 1;
}

# create the target version files
foreach (@ver_files) {
  system("touch $CURRENT_VERSION_DIR/$_");
  if ($? >> 8) {
    print "Error: Cannot change $CURRENT_VERSION_DIR. Config not changed\n";
    system("rm $CURRENT_VERSION_DIR/*");
    cleanup_save();
    exit 1;
  }
}

# now migrate.
system("$MIGRATE_SCRIPT $cfg_file");
# any failure will be reported by the migrate script.

# finally, restore the saved version files.
system("rm $CURRENT_VERSION_DIR/*");
cleanup_save();

exit 0;

