#!/pkg/bin/ksh
#
# Created by Mark Tooker, June 2006
#
# Viking platform-dependent "show tech-support" commands.
#
# Copyright (c) 2007-2019 by cisco Systems, Inc. 
# All rights reserved.
#----------------------------------------------------------------------

. /pkg/bin/show_tech_main_fragment

# Password flag to indicate whether log will include pw or not
__cardtype="unspecified"
__password="FALSE"
__sanitized="FALSE"
location=""
bridge_domain=0
no_statistics=0
bridge_domain_cli="-BridgeDomainAll"
bridge_domain_name=""
bd_id=""
hex_bdid_byteswapped="";

# Parse the arguments to the script.
while [ "$#" -gt "0" ]; do
    case "$1" in
        -a) shift 1;;
        -p) __password="TRUE"; shift 1;;
        -s) __sanitized="TRUE"; shift 1;;
        -t) __cardtype="$2"; shift 2;;
        -BridgeDomain) bd_id="$2"; bridge_domain=1; shift 2;;
        -no-statistics) no_statistics=1; shift 1;;
        *)  default_parser_function "$@"; shift $#;;
    esac
done

__parm1=`sysmgr_show -o -p exec | grep PID`
__parm2=`echo ${__parm1#*PID:}`
export EXEC_PID=$__parm2
BIN_DIR=/pkg/bin
LS_ONLY_EXEC=edrm_svr

if [ "$__cardtype" == "unspecified" ]; then
    __cardtype=`node_type`
fi

set_lc_specific_vars() {
    if [ -e $BIN_DIR/$LS_ONLY_EXEC ];then
	__lc_type="LIGHTSPEED"
    else
	__lc_type="LEGACY"
    fi
}

# This function retrieves the bg:bd format for the bdid and also
# converts the bd_id to hex, and performs a byteswap to be used 
# for NP struct search
extract_bd_info_using_bdid () {

    # Retrieve bridge-domain brief output, the first argument of the
    # array is the bg:bd output.

    # ensure bd-id is in base-10.
    bd_id=$(echo "obase=10; $bd_id" | bc)

    VAR="$(l2fib_show_client -BridgeDomainAll | grep "  $bd_id ")"
    set -A array $VAR
    bridge_domain_name=${array[0]};   

    bridge_domain_cli="-BridgeDomain $bridge_domain_name"

    hex_bdid=$(echo "obase=16; $bd_id" | bc)

    a[0]="$(echo "$hex_bdid" | cut -c 1)"
    a[1]="$(echo "$hex_bdid" | cut -c 2)"
    a[2]="$(echo "$hex_bdid" | cut -c 3)"
    a[3]="$(echo "$hex_bdid" | cut -c 4)"

    if [ ! -n "${a[0]}" ]; then
        a[3]="0"
        a[2]="0"
        a[1]="0"
        a[0]="0"
    fi

    if [ ! -n "${a[1]}" ]; then
        a[3]="${a[0]}"
        a[2]="0"
        a[1]="0"
        a[0]="0"
    fi

    if [ ! -n "${a[2]}" ]; then
        a[3]="${a[1]}"
        a[2]="${a[0]}"
        a[1]="0"
        a[0]="0"
    fi

    if [ ! -n "${a[3]}" ]; then
        a[3]="${a[2]}"
        a[2]="${a[1]}"
        a[1]="${a[0]}"
        a[0]="0"
    fi

    hex_bdid_byteswapped=${a[2]}${a[3]}${a[0]}${a[1]}
}

define_rack_nodes() {

    location=$ext_node_name
    node_list=`sdr_show_info -l | grep IOS | cut -c12-22`
    state_list=`sdr_show_info -l | grep IOS | cut -c40-51`
    __standby_node="FALSE"
    i=0; 
    for state in $state_list; do
        state_list[$i]=$state
        my_echo "state = $state"
        i=$(($i + 1))
        done    

    i=0; 
    for node in $node_list; do
        # check if this is a standby Node. If it is, show only command for this node
        # and ignore the other nodes that can be at a different release
        my_echo "node = $node"
        if [ $node == $location ]; then
           if [ ${state_list[$i]} == "Standby" ]; then
               __standby_node="TRUE"
           fi
        fi
        i=$(($i + 1))
        done    

    i=0; 
    j=0;
    for node in $node_list; do
        add_node="FALSE"
        # check if this is a standby Node. If it is, show only command for this node
        # and ignore the other nodes that can be at a different release
        if [ $__standby_node == "TRUE" ]; then
            # add node to the list only if this is the standby node 
            if [ $node == $location ]; then
               my_echo "Adding only standby node $node to the node list (ISSU requirement) "
               add_node="TRUE"
            else
               my_echo "Skip   normal       node $node  "
            fi
        else
            # add node to the list only if it is NOT a standby node
            if [ ${state_list[$j]} != "Standby" ]; then
               my_echo "Adding normal node $node to the node list "
               add_node="TRUE"
            else
               my_echo "Skip standby  node $node  "
            fi
        fi    

        if [ $add_node == "TRUE" ]; then
        location_list[$i]=$node
        int_node_name_list[$i]=`node_conversion -N ${location_list[$i]}`
        pq_nodeid_list[$i]=`node_conversion -I ${location_list[$i]}`
        fq_nodeid_list[$i]=`node_conversion -i ${int_node_name_list[$i]}`

        i=$(($i + 1))
        fi
        j=$(($j + 1))
        done    
    node_list_length=$i

}


# define our local macro to traverse only valid nodes
my_exec_commands_rack_nodes() {


    cmd_set="$1"
    rack_prefix=`uname -n | cut -d_ -f1`

    cmd_idx=1;
    location='$location'
    cmd_exec=$(eval "echo \${"$cmd_set"_exec[$cmd_idx]}")
    while [ -n "$cmd_exec" ]; do
        node_idx=0;
        while [ $node_idx -lt $node_list_length ]; do

            # initialize variables
 
            location=${location_list[$node_idx]}
            pq_nodeid=${pq_nodeid_list[$node_idx]}
            fq_nodeid=${fq_nodeid_list[$node_idx]}

            cmd_exec_loc=$(eval "echo $cmd_exec")
            cmd__ksh=$(eval "echo \${"$cmd_set"__ksh[$cmd_idx]}")
            cmd__ksh=$(eval "echo $cmd__ksh")

            add_commands "" "${cmd_exec_loc}" "${cmd__ksh}"
            node_idx=$(($node_idx + 1))

        done # end for

        # next command from array
        cmd_idx=$(($cmd_idx + 1))
        location='$location'
        cmd_exec=$(eval "echo \${"$cmd_set"_exec[$cmd_idx]}")
    done # end while
} 


# List each set of show commands to be run. Each set must finish with an empty
# string. Note that it is important to use single quotes rather than double 
# quotes for the strings containing your commands; showtech infra expects the command
# exactly the way it was entered.
# Use "\" ahead of any special character (eg. |) used in the command line.


# Commands for all nodes

if [ $no_statistics == 1 ]; then
AllNodes_exec[1]='show l2vpn forwarding bridge-domain $bridge_domain_name hardware ingress private no-statistics location $location'
AllNodes__ksh[1]='l2fib_show_client -l $fq_nodeid $bridge_domain_cli -I -p -q'
else
AllNodes_exec[1]='show l2vpn forwarding bridge-domain $bridge_domain_name hardware ingress detail location $location'
AllNodes__ksh[1]='l2fib_show_client -l $fq_nodeid $bridge_domain_cli -I -d'
fi

AllNodes_exec[2]='show l2vpn forwarding bridge-domain $bridge_domain_name mmrp hardware ingress detail location $location'
AllNodes__ksh[2]='l2fib_show_client -l $fq_nodeid $bridge_domain_cli -mmrp -I -d'
AllNodes_exec[3]='show l2vpn forwarding bridge-domain $bridge_domain_name mroute ipv4 hardware ingress detail debug location $location'
AllNodes__ksh[3]='l2fib_show_client -l $fq_nodeid $bridge_domain_cli -I -d -D -t'
AllNodes_exec[4]='show l2vpn forwarding bridge-domain $bridge_domain_name mroute ipv6 hardware ingress detail debug location $location'
AllNodes__ksh[4]='l2fib_show_client -l $fq_nodeid $bridge_domain_cli -I -d -D -s'
AllNodes_exec[5]='show l2vpn forwarding resource hardware ingress private location $location'
AllNodes__ksh[5]='l2fib_show_client -l $fq_nodeid -Resource -I -p'
AllNodes_exec[6]=''
AllNodes__ksh[6]=''


set_lc_buffer() {
    # the following set are commands that only need to be executed on a LC
    count=1
    AllNodes_LC_exec[$count]='show controllers np counters all location $location' 
    AllNodes_LC__ksh[$count]='prm_np_show counters -s $fq_nodeid'
    ((count+=1))
    AllNodes_LC_exec[$count]='show controllers np struct XID detail all all location $location'
    AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x0f -a 0x1 -m 0x7d0 -s $fq_nodeid'
    ((count+=1))
    if [ $__lc_type == "LIGHTSPEED" ]; then
        AllNodes_LC_exec[$count]='show controllers np struct XID-EXT detail all all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0xab -s $fq_nodeid'
        ((count+=1))
    fi
    AllNodes_LC_exec[$count]='show controllers np struct L2VPN-LDI detail all all location $location'
    AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x10 -s $fq_nodeid'
    ((count+=1))
    if [ $bridge_domain == 1 ]; then
        AllNodes_LC_exec[$count]='show controllers np struct BD search key $hex_bdid_byteswapped all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x11 -l $hex_bdid_byteswapped -s $fq_nodeid'
        ((count+=1))
        AllNodes_LC_exec[$count]='show controllers np struct BD-EXT search key $hex_bdid_byteswapped all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x94 -l $hex_bdid_byteswapped -s $fq_nodeid'
        ((count+=1))
        AllNodes_LC_exec[$count]='show controllers np struct L2FIB search key $hex_bdid_byteswapped start-index 12 all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x12 -l $hex_bdid_byteswapped -b 0xc -s $fq_nodeid'
        ((count+=1))
        AllNodes_LC_exec[$count]='show controllers np struct L2-BRGMEM search key $hex_bdid_byteswapped start-index 0 all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x1e -l $hex_bdid_byteswapped -b 0x0 -s $fq_nodeid'
    else
        AllNodes_LC_exec[$count]='show controllers np struct BD detail all all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x11 -s $fq_nodeid'
        ((count+=1))
        AllNodes_LC_exec[$count]='show controllers np struct BD-EXT detail all all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x94 -s $fq_nodeid'
        ((count+=1))
        AllNodes_LC_exec[$count]='show controllers np struct L2FIB all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x12 -s $fq_nodeid'
        ((count+=1))
        AllNodes_LC_exec[$count]='show controllers np struct L2-BRGMEM detail all all location $location'
        AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x1e -s $fq_nodeid'
    fi

    ((count+=1))
    AllNodes_LC_exec[$count]='show controllers np struct l2tp summary location $location'
    AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x3a -y 1 -s $fq_nodeid'
    ((count+=1))
    AllNodes_LC_exec[$count]='show controllers np struct L2MC-Lpbck detail all all location $location'
    AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x16 -s $fq_nodeid'
    ((count+=1))
    AllNodes_LC_exec[$count]='show controllers np struct L2MC-Results detail all all location $location'
    AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x14 -s $fq_nodeid'
    ((count+=1))
    AllNodes_LC_exec[$count]='show controllers np struct MSTI detail all all location $location'
    AllNodes_LC__ksh[$count]='prm_np_show struct -u 0x94 -s $fq_nodeid'
    ((count+=1))
    AllNodes_LC_exec[$count]=''
    AllNodes_LC__ksh[$count]=''
}

# The following are regularly cisco-support commands.

# this first set are command that can only be executed on the RP 
Support_RP_exec[1]='show l2vpn platform trace common all location $location'
Support_RP__ksh[1]='show_vkg_l2fib_ltrace -i $fq_nodeid -0 -T -U -E -R -C -V'
Support_RP_exec[2]='show l2vpn platform trace vpls pbb mac sec all location $location'
Support_RP__ksh[2]='show_vkg_l2fib_ltrace -i $fq_nodeid -3 -5 -6 -8 -T -U -E -R -C -V'
Support_RP_exec[3]='show l2vpn platform trace atom local all location $location'
Support_RP__ksh[3]='show_vkg_l2fib_ltrace -i $fq_nodeid -1 -2 -T -U -E -R -C -V'
Support_RP_exec[4]='show l2vpn platform trace snoop all location $location'
Support_RP__ksh[4]='show_vkg_l2fib_ltrace -i $fq_nodeid -4 -T -U -E -R -C -V'
Support_RP_exec[5]='show l2vpn platform trace l2tp l2tp-ipv6 all location $location'
Support_RP__ksh[5]='show_vkg_l2fib_ltrace -i $fq_nodeid -7 -9 -T -U -E -R -C -V'
Support_RP_exec[6]='show l2vpn platform trace-rp forwarding common all location $location'
Support_RP__ksh[6]='show_vkg_l2fib_rp_ltrace -0 -T -U -E -R -C -V'
Support_RP_exec[7]='show l2vpn platform trace-rp forwarding vpls all location $location'
Support_RP__ksh[7]='show_vkg_l2fib_rp_ltrace -1 -T -U -E -R -C -V'
Support_RP_exec[8]='show l2vpn platform trace-rp forwarding snoop all location $location'
Support_RP__ksh[8]='show_vkg_l2fib_rp_ltrace -2 -T -U -E -R -C -V'
Support_RP_exec[9]=''
Support_RP__ksh[9]=''

# the following set are commands that only need to be executed on a LC
Support_LC_exec[1]='show l2vpn forwarding message counters hardware location $location'
Support_LC__ksh[1]='l2fib_show_client -l $fq_nodeid -H'
Support_LC_exec[2]=''
Support_LC__ksh[2]=''

# the following will execute only on the RP

Common_exec[1]='show running-config'
Common__ksh[1]='nvgen -c -l 1 -t 1 -o 1'
Common_exec[2]='show platform'
if [[ -f /pkg/bin/show_platform_sysdb ]];then
    Common__ksh[2]='show_platform_sysdb'
elif [[ -f /pkg/bin/show_platform_vkg ]];then
    Common__ksh[2]='show_platform_vkg -e'
else 
    Common__ksh[2]="echo Show Platform Command is not available on this Platform"
fi
Common_exec[3]='show controller np ports all'
Common__ksh[3]='prm_np_show ports'
Common_exec[4]='show l2vpn bridge brief'
Common__ksh[4]='l2vpn_show -r 0x9'
Common_exec[5]='l2fib vqi database'
Common__ksh[5]='vkg_l2fib_vqi_test -bd'
Common_exec[6]=''
Common__ksh[6]=''

# A function called display() must be provided that calls the functions to 
# run the required show commands. The display() function is called in 
# /pkg/bin/show_tech_comp_file_frag

display() {
    print_heading "Executing specific commands on $__cardtype cardtype and $__location location " 

echo "This node info:  intnode $int_node_name extnode $ext_node_name location $location fq_nodeid $fq_nodeid" 

    if [ $bridge_domain == 1 ]; then
        extract_bd_info_using_bdid
    fi

    # Execute commands
    if [ "$__cardtype" == "SYS" ]; then
        print_heading "Executing common commands"
        exec_commands Common
    else 
        case "$__cardtype" in
        "LC")
            # execute the command only on a LC node
            print_heading "Executing specific commands on an LC node" 
            set_lc_specific_vars
            set_lc_buffer
	    exec_commands AllNodes_LC
            exec_commands AllNodes
            exec_commands Support_LC
            ;;
    
        "RP")
            # Execute commands only on the RP
            print_heading "Executing specific commands on an RP node" 
            exec_commands AllNodes
            define_rack_nodes
            my_exec_commands_rack_nodes Support_RP
            ;;
        esac
    fi
}

. /pkg/bin/show_tech_file_fragment
