#!/bin/sh
##
## tmpclone
##
## Clones and manages short-lived git repositories.
##
## Usage examples:
##
## tmpclone                 > list the tracked repos
## tmplcone -d              > deletes all tracked repos
## tmpclone -d target       > deletes the target
## tmpclone target          > opens the target, try to clone if not exits
## tmpclone -v target       > like tmpclone target, but deletes the repo after close
## tmpclone -r target       > like tmpcloen target, but if forces a redownload of the target 
## tmpclone -n name target  > creates a target with the name given, the target may be an url


function print_help()
{
    echo '
tmpclone [-dhrv] [-n NAME] [TARGET]
    Clones and manages short lived git repositories.
    
    -d
        If a target is provided this repo will be deleted. Otherwise all repos created by tmpclone will be deleted.

    -h
        Print this help page.
    
    -n NAME
        Explicitly define a name for the repo. This only work in combination with a target.
    
    -r 
        Recreates the repos before entering it.

    -v
        Delete the repo after exit (volatile).
    '
}


# -----------------------
# |  Argument parsing   |
# -----------------------

# Define default flag values
FLAG_D=false
FLAG_N=false
FLAG_N_VALUE=""
FLAG_R=false
FLAG_V=false

if [ $# -eq 0 ] 
then
    NO_ARGS=true
else
    NO_ARGS=false
fi

# Parse command-line options
while getopts ":dn:rvh" opt
do
    case ${opt} in
        h )
            print_help
            exit 0
            ;;
        d )
            FLAG_D=true
            ;;
        n )
            FLAG_N=true
            FLAG_N_VALUE=$OPTARG
            ;;
        r )
            FLAG_R=true
            ;;
        v )
            FLAG_V=true
            ;;
        \? )
            echo "Invalid option: -$OPTARG" 1>&2
            print_help
            exit 1
            ;;
        : )
            echo "Option -$OPTARG requires an argument." 1>&2
            print_help
            exit 1
            ;;
    esac
done

# Remove the options from the positional parameters
shift $((OPTIND -1))

# Check if there are any remaining arguments
if [ $# -eq 0 ] && ! $FLAG_D && ! $NO_ARGS
then
    echo "No TARGET was provided."
    print_help
    exit 1
fi

# Get the TARGET
TARGET=false
if [ $# -ne 0 ]
then
    TARGET=true
    TARGET_VALUE=$1
fi


# -----------------------
# |    Main program     |
# -----------------------

DATA_ROOT="/var/tmp/tmpclone"
mkdir -p "$DATA_ROOT"


function repo_with_name_exists()
{
    ls "$DATA_ROOT/$1" 1> /dev/null 2> /dev/null
    return $!
}

function repo_with_url_exists()
{
    repo_with_name_exists "$(get_name_from_url $1)"
    return $!
}

function get_name_from_url()
{
    echo "$1" | awk 'BEGIN{FS="/"} {print $NF}'
}

function get_url_from_name()
{
    cd "$DATA_ROOT/$1" && git remote get-url $(git remote | head -n 1)
}

function recreate_repo_from_name()
{
    local REPO_PATH="$DATA_ROOT/$1"
    local URL="$(get_url_from_name $1)"
    rm -rf "$REPO_PATH"
    git clone "$URL" "$REPO_PATH"
}

function recreate_repo_from_url() 
{
    local REPO_PATH="$DATA_ROOT/$(get_name_from_url $1)"
    rm -rf "$REPO_PATH"
    git clone "$1" "$REPO_PATH"
}


# Display all repos tracked by this script
if [ $NO_ARGS = true ]
then
    ls $DATA_ROOT | sed "s/ /\n/g"
    exit 0
fi

# Convert target to path
TARGET_PATH=""
if [ $TARGET = true ]
then
    if repo_with_name_exists $TARGET_VALUE
    then
        TARGET_PATH="$DATA_ROOT/$TARGET_VALUE"
    elif repo_with_url_exists $TARGET_VALUE
    then
        TARGET_PATH="$DATA_ROOT/$(get_name_from_url $TARGET_VALUE)"
    fi
fi

# Delete repos on -d option call
if [ "$FLAG_D" = true ]
then
    if [ $TARGET = false ]
    then 
        rm -rf "$DATA_ROOT"
        echo "All repositories deleted."
    else
        rm -rf "$TARGET_PATH"
        echo "Deleted the repo $TARGET_PATH."
    fi
    exit 0
fi

# Use name option to recreate a target with a new name
if [ "$FLAG_N" = true ]
then
    TARGET_PATH="$DATA_ROOT/$FLAG_N_VALUE"

    if repo_with_name_exists $TARGET_VALUE
    then
        git clone "$(get_url_from_name $TARGET_VALUE)" "$TARGET_PATH"
    elif repo_with_url_exists $TARGET_VALUE
    then
        git clone "$TARGET_VALUE" "$TARGET_PATH"
    else
        echo "Target '$TARGET_VALUE' not found."
        exit 1
    fi
fi

# Check if there exists a repo with the url already.
if [ $FLAG_R = true ]
then
    if repo_with_name_exists $TARGET_VALUE
    then
        recreate_repo_from_name $TARGET_VALUE 
    elif repo_with_url_exists $TARGET_VALUE
    then
        recreate_repo_from_url $TARGET_VALUE 
    else
        echo "Target '$TARGET_VALUE' not found."
        exit 1
    fi
fi

# Create if not exists
if [ ! -d "$TARGET_PATH" ]
then
    TARGET_PATH="$DATA_ROOT/$(get_name_from_url $TARGET_VALUE)"
    git clone "$TARGET_VALUE" "$TARGET_PATH"
fi

# Define promt prefix
if [ "$FLAG_V" = true ]
then
    export PROMPT_PREFIX="%F{244}%F{red}[tmpclone] %F{reset}"
else
    export PROMPT_PREFIX="[tmpclone] "
fi

# Enter the subshell
sh -c "cd \"$TARGET_PATH\"; /bin/zsh"
SHELL_EXIT=$?

# Volatile
if [ "$FLAG_V" = true ]
then
    rm -rf "$TARGET_PATH"
fi

exit $SHELL_EXIT
