#!/bin/bash

# Need to set path in case this is invoked as the admin user
export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin

main(){
 while getopts 'pdehc' c
 do
  case $c in
   d) set -x;; # Enable debugging
   h) echo "USAGE: Gen7_migration [-hedc] [-p <file]"
      echo "         -h: Display help and usage"
      echo "         -d: Turn on shell debugging"
      script_over="True" ;;
  esac
 done
 if [[ $script_over != "True" ]]; then
  Gen7_VF;
 fi }

Gen7_VF(){	# VF file Gen6 to Gen7 port index migration
awk '
FNR==1{ if(nsw)doit()					# print file whenever a new one starts
 close(ot);split(FILENAME,w,".");ot=w[1]"."w[2]+14 # calculate output file name (input file name plus 14 to switch to new SWBD) when beginning each file
 nsw=0;split("",line);c="";split("",ports);split("",u)}		# clear variables
/^SWITCH/||/^SYSTEM/{sw=$0;asw[++nsw]=sw;next}				# Beginning of switch section
/ATTRIBUTE/&&/DS:1/{ds=sw}				# find default switch
$1=="PORTMAP"&&$2~/^FC:\[/{				# look for FC PORTMAPs
 e[nsw]=substr($0,1,index($0,"FC:")-1)	# save leading spaces
 split($2,p,"[\\[\\]]")					# get index ranges
 n=split(p[2],q,"[,:]")					# load ranges into array
 for(i=1;i<=n;i++){						# for each range
  ns=split(q[i],s,"-")					# find begin and end of range
  if(ns==1){u[nsw]=u[nsw]":"q[i];continue}		# if not a range save it
  for(j=s[1];j<=s[2];j++){				# For each port index in each range
   if(FILENAME~/\.165/){t=tr_V(j)	# Do translation Venator 
   if(ds!=sw && t>=384 && t<=487  ){c=c" "t}else{ports[nsw]=ports[nsw]" "t}}		#if a core port, save it and dont add to this FID       
   else if(FILENAME~/\.166/){t=tr_A(j)	# Do translation Allegience
   if(ds!=sw && t>=768 && t<=895  ){c=c" "t}else{ports[nsw]=ports[nsw]" "t}}		#if a core port, save it and dont add to this FID       
   else{print "ERROR:Wrong switch type "FILENAME;exit}}}
} 
{ line[nsw]=line[nsw]"\n"$0 }			# save all lines for each switch section
END{doit()}								# print last file

func doit(  n,i,pr){					# print all lines in each switch entry - parameters spaced to right are local variables
 for(i=1;i<=nsw;i++){					# for each switch entry
  if(asw[i]==ds){pr=rangeit(ports[i]" "c)	# if this is default switch, add core indexes, convert to ranges   
  }else{pr=rangeit(ports[i])}			# convert to ranges of ports
  print asw[i] > ot						# print switch entry header
  n=split(line[i],p,"\n") 				# go thru switch entry line by line
  for(j=1;j<=n;j++){								# for each line
  if(p[j]~/ETHSW_ENABLED:/){						# if this is the line with ETHSW_ENABLED:
    print p[j] > ot									# print as is
    print "\tATTRIBUTE\tDAA_ENABLED:1" > ot 		# add DAA_ENABLED line
  }else if(p[j]~/DAA_ENABLED:/){					# if this is the line with DAA_ENABLED:
													# Skip the existing line, if any
  		}else if(p[j]~/FC:\[/){						# if this is the line with FC:
			    print e[i]"FC:["pr u[i]"]" > ot		#reconstruct line with new indexes
		   	 }else{print p[j] > ot}}}}			# print out all other lines
   
func rangeit(s,  t) {   				# sort and put ports in ranges - parameters spaced to right are local variables
 split(s,t," ")							# load into array
 nt=asort(t)							# sort all the port indexes
 v="";z=10000							# Start of Combine index numbers into ranges - init variables
 for(i=1;i<=nt;i++){					# loop thru indexes - find if exactly one greater than last index
  if(t[i]-z==1)r=t[i]					# range still going
  else{f();v=v","t[i]}					# end range found - output current range - start next range
  z=t[i]}								# set previous value
 f();return(substr(v,8))}				# return list string    
func f(){if(r)v=v"-"r;else v=v"-"z;r=0}	# output end of range

func tr_V(x){return x+32*int(x/64)+16*int(x/272)-720*int(x/736)-48*int(x/784)}  # Translate Gen6 index to Gen7 index on Venator or Allegience
func tr_A(x){return x+80*int(x/16)-752*int(x/128)+720*int(x/384)-80*int(x/400)-48*int(x/416)-80*int(x/432)-1280*int(x/768)\
+80*int(x/800)+48*int(x/832)+80*int(x/864)-16*int(x/1152)-80*int(x/1168)-48*int(x/1184)}' /etc/fabos/config/vf-conf.16[56] /etc/fabos/config/switch-conf.16[56] /etc/fabos/config/vf-conf-new.16[56] \
/mnt/etc/fabos/config/vf-conf.16[56] /mnt/etc/fabos/config/switch-conf.16[56] /mnt/etc/fabos/config/vf-conf-new.16[56]; }

main "$@"											# using a "main" function allows program to be shown first, and then subroutines 
