#!/bin/bash 

# RANCID diff filter
# jwbensley@gmail.com

# This script filters a rancid diff file to remove unwanted "sections" which are updates for a device
# which contain update info, but no config changes. I don't wish to receive these updates via email.
# These are emails that have the same number of lines that start with "-" as "- !", and the same number
# of lines that start with "+" as "+ !", so all lines in the update where not config changes.



diff="$1"

# Remove any files from the last run if they exist
if [ -a $diff.filter ]
then
    rm $diff.filter
fi

# Number of device sections in the diff file, they are seperated by these long strings of equal signs
sectionCount=$(grep -c "=======================================" $diff)
# Geat each device section into an Array so we can examine if it's worth keeping
declare -a sections
sections=( $(awk '/=======================================/ {print FNR}' $diff) )


# Create an Array and index value, of start and end line numbers in the rancid diff file that represent device
# sections within the diff file we want to remove using sed at the end
l=0
declare -a unwanted
ischanged=0


if [[ $sectionCount -gt 1 ]]
then

    # Loop through each device section in the rancid diff
    for s in `seq 1 ${#sections[@]}`
    do

        # $sstart = first line of section, $send = last
        # $range = line  numbers inclusive of start and end
        sstart=${sections[($s-1)]}
        let sstart=$sstart-1
        send=${sections[($s)]}
        let send=$send-2
        let range=$send-$sstart
        # Lines that start with a minus "-"
        minuslines=( $(head -n $send $diff | tail -n $range | grep -c "^\-") )
        # Lines that start with a plus "+"
        pluslines=( $(head -n $send $diff | tail -n $range | grep -c "^\+") )
        # Lines that start with "- !"
        junkminuslines=( $(head -n $send $diff | tail -n $range | grep -c "^\-\ \!") )
        # Lines that start with "+ !"
        junkpluslines=( $(head -n $send $diff | tail -n $range | grep -c "^\+\ \!") )

        if [[ $minuslines -eq $junkminuslines && $pluslines -eq $junkpluslines ]]
        then 

            # Here we are building an array of start and end line numbers of unwanted sections to remove
            # at the end using sed
            let l=$l+1
            unwanted[$l]=$sstart
            let l=$l+1
            unwanted[$l]=$send
            
        fi

    done

    echo "Do lines need deleting: ${#unwanted[@]}"
    cat $diff

    # Check if we found lines that need deleting...
    if [[ ${#unwanted[@]} -ge 2 ]]
    then

        echo "Lines need deleting"

        # Build the sed argument do delete multiple lines in place in the diff file
        # Example: sed --inplace 1,15d; 28,89d; diff.file
        sedarg=""
        for j in `seq 1 ${#unwanted[@]}`
        do
            sedarg="$sedarg${unwanted[$j]},"
            let j=$j+1
            sedarg="$sedarg${unwanted[$j]}d;"
            if [[ $j -eq ${#unwanted[@]} ]]; then
                break
            fi
        done
        echo "$sedarg"
        echo "$diff.filter"
        sed "$sedarg" "$diff" > "$diff".filter
        ischanged=1

    fi

fi # sections > 1

if [[ $sectionCount -eq 1 ]]
then
        # Lines that start with a minus "-"
        minuslines=( $(cat $diff | grep -c "^\-") )
        # Lines that start with a plus "+"
        pluslines=( $(cat $diff | grep -c "^\+") )
        # Lines that start with "- !"
        junkminuslines=( $(cat $diff | grep -c "^\-\ \!") )
        # Lines that start with "+ !"
        junkpluslines=( $(cat $diff | grep -c "^\+\ \!") )

        if [[ $minuslines -eq $junkminuslines && $pluslines -eq $junkpluslines ]]
        then
            echo -n "" > $diff.filter
            ischanged=1
        fi

fi

if [ $ischanged -eq 1 ]
then
        # Mail the origina to me before modifying it
        (
          echo "To: jwbensley@gmail.com"
          echo "Subject: rancid diff changes"
          echo "The following output was edited"
          cat $diff
        ) | sendmail -t
fi
