#!/bin/bash
# Pivot: The handy diretory switch
# Examples:
# /root/a/b/c/d $ swing a k
# /root/k/b/c/d $ swing k g
# /root/g/b/c/d $ swing b f
# /root/g/f/c/d $

function pvt() {
    ARG1=$1; ARG2=$2; ARG3=$3;

    if [[ -z "$ARG1" ]]; then
        __func_head "[MODE] PIVOT_DIR LAND_DIR"
        echo
        return 1
    fi

    case "$ARG1" in
        p)
            CC='pushd' ;;
        c)
            CC='cd' ;;
        e)
            CC='echo' ;;
        *)
            CC='cd'
            ARG3=$ARG2
            ARG2=$ARG1
            ;;
    esac

    if [[ -z "$ARG3" ]]; then
        >&2 echo "Error: LAND_DIR is not defined"
        pvt
        return 1
    fi

    IFS="/" read -a PWDA <<< "$(pwd)"

    # Begin finding dirs in up-stack
    MARK=0
    LISTOF=''
    UP_STACK=''
    for i in "${!PWDA[@]}"
    do
        DIR=${PWDA[$i]}

        if [[ -n "$DIR" ]]; then
            LISTOF="$LISTOF\n    $DIR";
        fi

        if [[ "$DIR" =~ $ARG2 ]]; then
            MARK=$i
            continue
        fi

        if [[ $MARK -ne 0 ]]; then
            UP_STACK="$UP_STACK/$DIR"
        fi
    done

    if [[ $MARK -eq 0 ]]; then
        echo "No such token in up stack: $ARG3"
        echo -e $LISTOF;
        echo
        return 1
    fi

    PARENT_DIR='/'

    for (( i=1; i<$MARK; i++ ))
    do
        PARENT_DIR="$PARENT_DIR${PWDA[$i]}/"
    done

    CAND=()
    for i in $( find $PARENT_DIR -maxdepth 1 -type d -name "*$ARG3*" )
    do
        CAND+=("$i")
    done

    for i in "${!CAND[@]}"
    do
        DIR="${CAND[$i]}"
        LAND_DIR="$DIR$UP_STACK"

        if [[ -d "$LAND_DIR" ]]; then
            $CC "$LAND_DIR"
            return 0
        fi
    done

    echo "Error: Cannot land to \"$UP_STACK\" under pivoting parent: \"$PARENT_DIR\""
    echo "List of possible landings:"
    for i in $( find $PARENT_DIR -maxdepth 1 -type d )
    do
        LAND_DIR="$i$UP_STACK"
        if [[ -d "$LAND_DIR" ]]; then
            echo "    "$( basename $i )
        fi
    done

    echo

    return 1
}