#!/bin/env bash
#
# Written by Anthony Lobianco, 01/23/2014
#
# A simple script to batch rename television files
#
# USAGE
# -----
# chmod a+x tv_rename.sh
# ./tv_rename.sh -d /path/to/show/S01
#
# CHANGELOG
# ---------
#
# 1.0.0
# -----
# initial commit
#
# 1.0.1
# -----
# check to make sure input directory exists
#
# 1.0.2
# -----
# handle file types other than .mkv
# make sure new format has same extension as old file
# make sure new format includes the SXXEYY placeholder
#
# 1.0.3
# -----
# if SXXEYY pattern is not present, automatically determine it from filename
#

VRS=1.0.3

bold=`tput bold`          # bold characters in echo
normal=`tput sgr0`        # normal characters in echo

echo " "
echo "BATCH RENAME SCRIPT v$VRS"
echo -n "server: "
echo $SSH_CONNECTION | awk '{print $3}'
echo " "

DIR=""

while getopts ":d:" OPTION
do
    case $OPTION in
        d)
	    if [ "$OPTARG" = "." ]; then
	        DIR=`pwd`
	    else
	        DIR="$OPTARG"
	    fi
	;;	
    esac
done

if [ "$DIR" = "" ]; then
    echo "no directory specified (use -d /path/to/directory/)"
    echo "EXIT"
    exit 1
elif [ ! -d "$DIR" ]; then
    echo "$DIR does not exist"
    echo "EXIT"
    exit 1
fi

echo -e "renaming files in:\t ${bold}${DIR}${normal}"

LAST_FILE=`ls -l "$DIR" | tail -1 | awk '{print $NF}'`
FILE_TYPE=`basename $LAST_FILE | awk -F . '{print $NF}'`

echo -e "last file looks like:\t ${bold}${LAST_FILE}${normal}\n"

rename_files() {
    local format=$1
    local dry_run=$2

    # find SXXEYY pattern
    REGEX="([sS]([0-9]{2,}|[X]{2,})[eE]([0-9]{2,}|[Y]{2,}))"
    if [[ ! $format =~ $REGEX ]]; then
        echo "could not find SXXEYY pattern in new format"
	echo " "
	continue
    else
        MATCH="${BASH_REMATCH[1]}"
    fi

    # needed if directory name has whitespace (e.g. /media/Family Guy/)
    SAVEIFS=$IFS
    IFS=$(echo -en "\n\b")

    SEASON=`basename "$DIR"`
    EPISODE=1
    for ITEM in $(find "$DIR" -type f -name "*.${FILE_TYPE}" | sort); do
        if (( $EPISODE < 10 )); then
	    SE="${SEASON}E0${EPISODE}"
	else
	    SE="${SEASON}E${EPISODE}"
	fi

	if [[ $MATCH != $SE ]]; then
	    FILE="${format/$MATCH/$SE}"
	else
	    FILE=$format
	fi

	# list the files during dry run, rename them otherwise
	if $dry_run; then
	    echo -e " mv `basename $ITEM` \n -> $FILE"
	else
	    if [[ `basename $ITEM` == $FILE ]]; then
	        echo "rename not needed for `basename $ITEM`"
	    else
	        echo -e "renaming $ITEM \n to -> \t $DIR/$FILE"
		mv $ITEM "$DIR/$FILE"
	    fi
	fi

	echo " "

	EPISODE=$((EPISODE + 1))
    done

    IFS=$SAVEIFS
}

echo "what format do you want to use to rename files?"
echo -e "(ex: Breaking.Bad.SXXEYY.1080p.BluRay.DTS.x264-rovers.mkv)\n"

while read -ep "[format]: " FORMAT
do
    echo " "

    # do some error checks
    if [[ $FORMAT != *.${FILE_TYPE} ]]; then
        echo "make sure new format has same file type extension (.${FILE_TYPE})"
	echo " "
	continue
    fi

    rename_files $FORMAT true

    echo " "

    while read -ep "[continue? y/n]: " CONTINUE
    do
        if [[ $CONTINUE = y ]]; then
	    break
	else
	    continue 2
	fi
    done

    echo " "

    rename_files $FORMAT false

    break
done

echo " "
echo "DONE"
exit 0
