#!/usr/bin/perl
#
# Migration script to handle the move of:
#
#   interface multilink <ifname> ip
#
# to:
#
#   interface multilink <ifname> vif 1 ip
#
#

use strict;
use lib "/opt/vyatta/share/perl5/";
use XorpConfigParser;

# Enable/disable debug output.
my $debug = undef;

#
# The output() function becomes unhappy if you give it a children
# array that has an undefined entry in the middle.  That's true even
# though the delete_child() function will do just that!  So, we clean
# the array up right here.  This function squeezes out any undefined
# entry in the array that is passed in.
#
# XXX delete_child should use splice.
sub compress_children_array {
    my ($children) = @_;

    my $from;
    my $to;
    for ($from = 0, $to = 0; $from < @$children; $from++) {
	if (defined(@$children[$from])) {
	    if ($from > $to) {
		@$children[$to] = @$children[$from];
	    }
	    $to++;
	}
    }

    for ( ; $to < $from ; $to++ ) {
	@$children[$to] = undef;
    }
}

if (defined($debug)){ printf("Starting...\n"); }

my $orig_cfg = shift;
exit 1 if (!defined($orig_cfg));

my $xcp = new XorpConfigParser();
$xcp->parse($orig_cfg);

my $hashInterfaces = $xcp->get_node(['interfaces']);
if (defined($hashInterfaces)) {
    if (defined($debug)){ printf ("Found interfaces\n"); }

    my $childrenInterfaces = $hashInterfaces->{'children'};
    if (defined($childrenInterfaces)) {
	# Iterate through the interfaces
	foreach my $hashInterface (@$childrenInterfaces) {
	    if (defined($debug)){ 
		printf("Found interface: %s\n", $hashInterface->{'name'});
	    }
	    my $children = $hashInterface->{'children'};
	    if ($hashInterface->{'name'} =~ /multilink/) {
		if (defined($debug)){ printf("Its a multilink\n"); }

		if (defined($children)) {
		    my $ip_child = $xcp->find_child($children, "ip");
		    if (defined($ip_child)) {
			if (defined($debug)){ printf("Found IP\n"); }
			if (defined($debug)){ printf("Deleting IP\n"); }
			$xcp->delete_child($children, "ip", "moved");
			compress_children_array($children);
			my $vif = 
			    $xcp->find_child($children, "vif 1");
			if (defined($vif)) {
			    if (defined($debug)){ printf("Found vif\n"); }
			    my $vif_children = $vif->{'children'};
			    push(@$vif_children, $ip_child);
			}
		    }
		}
	    } elsif ($hashInterface->{'serial'} eq 'serial') {
		# interfaces/serial/X/qos-policy was a mistake introduced
		# in islavista but later removed
		my $qos_child = $xcp->find_child($children, "qos-policy");
		if (defined($qos_child)) {
		    $xcp->delete_child($children, "qos-policy",
				       "not implemented");
		    compress_children_array($children);
		}
	    }
	}
    }
} else {
    if (defined($debug)){ printf("No interfaces multilink\n"); }
}


my $tmpfile = "/tmp/vyatta_migrate_serial.$$";
open (my $tmp, '>', $tmpfile)
    or die "Can't open $tmpfile: $!";

select $tmp;
$xcp->output(0);
close $tmp;

if (defined($debug)){ printf("Re-writing config file!\n"); }

my $ret = system("mv $tmpfile $orig_cfg");
exit 1 if ($ret >> 8);

if (defined($debug)){ printf("done!\n"); }

exit 0;
