#!/usr/local/bin/perl
#
# Program to output murphi code that simulates an arbitrary topology.
# 
sub mkmatrix {
    my($rows, $cols) = @_;
    --$rows; --$cols;
    my $count = 1;
    my @mx = ();
    foreach (0 .. $rows) {
    my @row = ();
    $row[$_] = $count++ foreach (0 .. $cols);
    push(@mx, \@row);
    }
    return(\@mx);
}

sub print_topo
{

    my ($num, $topo_mat) = @_;
    
    
for($myi=0;$myi<$num;$myi++)
{
	
	for($j=0;$j<$num;$j++)
	{
	    if($topo_mat->[$myi][$j]==1)
	    {
		print  "\ttopology[$myi][$j] := true;\n";
	    }
	    else
	    {
		print  "\ttopology[$myi][$j] := false;\n"
	    }
      	}	

}


}

sub make_topo_mat
{
my ($num, @topo) = @_;
$topo_mat= mkmatrix($num,$num);

$count =1;
for($i=0;$i<$num;$i++)
{
	#skipping blank lines
	while($topo[$count]=~ /^$/)
	{
	     $count++;

	     if($count>$#topo)
	     {
		 break;
	     }
	}
	if($count >$#topo)
	{	  
	  break;
        }
	
	@temp = split(/ /,$topo[$count]);
	
	
	for($j=0;$j<$num;$j++)
	{
		$topo_mat->[$i][$j]=($temp[$j]);
	
	}	
	$count++;
}
$topo_mat
}


#should return how far the code has gone thus far
sub good_node_rule
{
    my ($current, $numgood,$numbad,@murph) = @_;
    
    
    $current++;
    while(!($murph[$current] =~/%GOODRULEEND/)){
	push @goodrule,$murph[$current];
	
	$current++;
    }
    
    
    for($i=0;$i<$numgood;$i++)
    {
	for($j=0;$j<$numgood+$numbad;$j++)
        {
	    for($k=0;$k<$numgood+$numbad;$k++)
            {
		for($l=0;$l<=$#goodrule;$l++)
		{
		    
		    $temp= $goodrule[$l];
		    $temp=~ s/%GOODNODEID/$i/g;
		    $temp=~ s/%NODEID/$j/g;
		    $temp=~ s/%ROUTETABLEID/$k/g;
		    print $temp;
		    
		    
		}
		print "\n";
	    }
	    
	}

    }
    
   $current;

}

sub bad_node_rule
{
    my ($current, $numgood,$numbad,$maxseqno,@murph) = @_;
    
    
    $current++;
    while(!($murph[$current] =~/%BADRULEEND/)){
	push @badrule,$murph[$current];
	
	$current++;
    }
    
    
    
    for($i=$numgood;$i<$numbad+$numgood;$i++)
    {
	for($j=0;$j<$numgood+$numbad;$j++)
        {
	    for($k=0;$k<$numgood+$numbad;$k++)
            {
		#seqno
		for($a=0;$a<$numgood+$numbad;$a++)
		{
		    #dist
		    for($b=0;$b<$numgood+$numbad;$b++)
		    {
		
			for($l=0;$l<=$#badrule;$l++)
			{
		    
			    $temp= $badrule[$l];
			    $temp=~ s/%BADNODEID/$i/g;
			    $temp=~ s/%NODEID/$j/g;
			    $temp=~ s/%ROUTETABLEID/$k/g;
			    $temp=~ s/%SEQNO/$a/g;
			    $temp=~ s/%DIST/$b/g;
			    print $temp;
		    
		    
			}
			print "\n";
		    }
		}
	    }
	    
	}

    }
    
   $current;

}


    


$topo_file_name = $ARGV[1];
$input_file_name = $ARGV[0];

open(TOPO, $topo_file_name);		# Open the file
open(INFILE, $input_file_name);		# Open the file
@topo = <TOPO>;		# Read it into an array
@murph = <INFILE>;

close(TOPO);			# Close the file
close(INFILE);


@numgoodbad = split(/ /, $topo[0]);
$numgood = $numgoodbad[0];
$numbad = ($numgoodbad[1]);
$maxseqno = $numgoodbad[2]; 

$chmaxseqno =chomp($maxseqno);




$topo_mat=make_topo_mat(($numgood+$numbad),@topo);


for($i=0;$i<=$#murph;$i++)
{
    
     
     if($murph[$i] =~ /%GOODRULESTART/)
     {
	
	$i=good_node_rule($i,$numgood,$numbad,@murph);	
	
	
    }
#notice the fall through
     if($murph[$i] =~ /%BADRULESTART/)
     {
	
	$i=bad_node_rule($i,$numgood,$numbad,$maxseqno,@murph);	
	
	
    }
     if($murph[$i] =~ /%TOPOMAT/)
     {
	# print "Before I is $i";
	 print_topo($numgood+$numbad,$topo_mat);
	 #print "After I is $i";
	# exit(0);
     }
     else
     {
     
	 $murph[$i] =~ s/%NUMGOODNODES/$numgood/;
	 $murph[$i] =~ s/%NUMBADNODES/$numbad/;
	 $murph[$i] =~ s/%MAXSEQNO/$chmaxseqno/;
	 $murph[$i] =~ s/%BADRULEEND//;
	 $murph[$i] =~ s/%GOODRULEEND//;
	 print $murph[$i];
     }
  

}
































