#!/bin/bash
#==============================================================================
# j2_olist_chain_dump
#
# Dumps the olist chain for J2 platform
#
# Copyright (c) 2021 by cisco Systems, Inc.
# All rights reserved.
#==============================================================================

MCDB_INDEX_START=
REVERSE=
FILE=

print_help() {
    cat <<EOF
usage j2_olist_chain_dump  (arg) FILE
      -i,   --mcdb_index     give index of MCDB. mcdb_index = mcid(fgid) + MTM_EGR_MCDB_OFFSET|MTM_ING_MCDB_OFFSET
      -r,   --reverse        traverse the olist chain in reverse, default is forward
      -f,   --file           mcdb dump file
      -h,   --help           print this message

Example:
-- dump MCDB chain forward
j2_olist_chain_dump -i|--mcdb_index 262101 -f mcdb_dump.txt

-- dump MCDB chain backwards
j2_olist_chain_dump -i|--mcdb_index 262101 -r|--reverse -f mcdb_dump.txt
EOF
}

print_header() {
    cat <<EOF
===============================================================
| #      | MCDB_  || NEXT_  | CUD    | DESTINATION            |
|        | INDEX  || PTR    |        |                        |
===============================================================
EOF
}

mcdb_traverse_forward() {
    start_mcdb_index=$1
    file=$2

    cur_mcdb_index=$start_mcdb_index

    while [ -n "$cur_mcdb_index" ] && [ "$cur_mcdb_index" != "262143" ];do
        var=
        var1=

        while IFS= read -r line;do
            var=`echo "$line" | awk '{print $4}'`
            if [ "$var" = "$cur_mcdb_index" ]; then
                echo "$line"
                var1=`echo "$line" | awk '{print $6}'`
                break
            fi
        done < <(cat $file | grep $cur_mcdb_index)
        cur_mcdb_index=$var1
    done

    return
}

mcdb_traverse_backward() {
    start_mcdb_index=$1
    file=$2

    cur_mcdb_index=$start_mcdb_index

    while [ -n "$cur_mcdb_index" ];do
        var=
        var1=

        while IFS= read -r line;do
            var=`echo "$line" | awk '{print $4}'`
            if [ "$var" = "$cur_mcdb_index" ]; then
                echo "$line"
            fi

            var=`echo "$line" | awk '{print $6}'`
            if [ "$var" = "$cur_mcdb_index" ]; then
                var1=`echo "$line" | awk '{print $4}'`
                break
            fi
        done < <(cat $file | grep $cur_mcdb_index)
        cur_mcdb_index=$var1
    done

    return
}

TEMP=`getopt -o i:f:rh -l mcdb_index:,help -n j2_olist_chain_dump -- "$@"`
if [ "$?" -ne 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

EMPTY_INPUT='^[ ]+--([ ]*$|[ ]+)'
[[ "$TEMP" =~ $EMPTY_INPUT ]] && echo "invalid input" && print_help && exit 2;

eval set -- "$TEMP"

while true; do
    case "$1" in
         -i | --mcdb_index ) MCDB_INDEX_START="$2"; shift 2;;
         -r | --reverse) REVERSE="reverse"; shift 1;;
         -f | --file) FILE="$2"; shift 2;;
         -h | --help) print_help; break ;;
         -- ) shift; break ;;
         * ) break ;;
    esac
done

DIRECTION="${REVERSE:-Forward}"

echo "MCDB START INDEX: $MCDB_INDEX_START"
echo "Traversing direction: $DIRECTION"
echo "MCDB dump file $FILE"
echo ""
echo ""

## can't print header because different formats(single CUD, double CUD) have
## different headers and mcid can have multiple format OLEs
#print_header

if [ -n "$REVERSE" ]; then
    mcdb_traverse_backward "$MCDB_INDEX_START" "$FILE"
else
    mcdb_traverse_forward "$MCDB_INDEX_START" "$FILE"
fi
