#!/bin/sh
set -e

if [ ! `which virtualenv` ];then
    echo "virtualenv not found, (eg.sudo apt-get install python-virtualenv)"
    exit
fi

envdir=
envbindir=
envpip=
envpython=
envlib=
envdocdir=
sourcefile=
cachedir="$HOME/.pypi"

if [ ! -d $cachedir ]; then
    mkdir -p $cachedir
    alert="$cachedir/alert.txt"
    echo "This directory was created by orb as a download cache." > $alert
    echo "You can delete this file." >> $alert
fi

locate_environment () {
    dir=`pwd`
    until [ "$dir" = "/" ]; do
        f="$dir/.orb"
        if [ -f $f ]; then
            sourcefile="$f"
            envdir="$dir"
            envbindir="$envdir/bin"
            envpip="$envbindir/pip"
            envpython="$envbindir/python"
            envlib=`$envpython -c "from distutils.sysconfig import get_python_lib;print(get_python_lib())"`
            envdocdir="$dir/doc"
            return
        fi
        dir=`dirname $dir`
    done
    echo "not a virtual environment"
    exit 1
}

orbname=

canonical_name () {
    #make absolute and add extension '.orb'
    dir=`dirname $1`
    name=`basename $1`
    orbname="`cd $dir; pwd`/$name"
    ext=`echo $name | sed 's/.*\.//g'`
    if [ $ext != "orb" ]; then
        orbname="$orbname".orb
    fi
}

#from pip
deactivate () {

    if [ -n "$_OLD_VIRTUAL_PATH" ] ; then
        PATH="$_OLD_VIRTUAL_PATH"
        export PATH
        unset _OLD_VIRTUAL_PATH
    fi

    # This should detect bash and zsh, which have a hash command that must
    # be called to get it to forget past commands.  Without forgetting
    # past commands the $PATH changes we made may not be respected
    if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
        hash -r
    fi

    unset VIRTUAL_ENV
}

#from pip
activate () {

    VIRTUAL_ENV="$envdir"
    export VIRTUAL_ENV

    _OLD_VIRTUAL_PATH="$PATH"
    PATH="$VIRTUAL_ENV/bin:$PATH"
    export PATH

    # This should detect bash and zsh, which have a hash command that must
    # be called to get it to forget past commands.  Without forgetting
    # past commands the $PATH changes we made may not be respected
    if [ -n "$BASH" -o -n "$ZSH_VERSION" ] ; then
        hash -r
    fi
}

usage () {
    echo "Usage:"
    echo "orb init [--help]"
    echo "orb install [--help]"
    echo "orb ls"
    echo "orb lib"
    echo "orb symlink EXISTING_ENV [NEW_ENV]"
    echo "orb download PACKAGE [DEST]"
    echo "orb *.py [OPTIONS]"
    echo "orb [ANY SHELL COMMAND]"
}

case "$1" in
"init")
    # TODO: various YAGNI incantations, needs more work but the following are well used:
    #
    # new environment:
    #     orb init myproj
    # new environment + install requirements + (if requirements is from a source repo) install editable package:
    #     orb init /path/to/a/requirements/file myproj
    if [ ! $2 ]; then
        if [ -f "REQUIREMENTS" ]; then
            orb init REQUIREMENTS
        else
            echo "ERROR: missing env name or requirements file"
            exit 1
        fi
    else
        if [ "$2" = "--help" ]; then
            # TODO: lazy bastard...
            virtualenv $@ | sed "s/Usage: virtualenv/Usage: orb init/g"
            exit
        elif [ -f $2 ]; then
            # create from requirements file
            reqfiledir=`dirname $2`
            reqfile=`basename $2`
            reqfile="`cd $reqfiledir; pwd`/$reqfile"
            reqfiledir=`dirname $reqfile`
            if [ -d "$reqfiledir/.git" ]; then
                prefix="git"
                branch="master"
            elif [ -d "$reqfiledir/.hg" ]; then
                prefix="hg"
                branch="tip"
            fi
            if [ $prefix ] && [ -f "$reqfiledir/setup.py" ]; then
                # requirements file is from an installable repo
                eggname=`basename $reqfiledir`
                if [ $3 ]; then
                    envname=$3
                else
                    envname=$branch
                fi
                repo="$prefix+file://$reqfiledir@$branch#egg=$eggname"
                # install repo
                orb init $repo $envname $reqfile
            else
                # the requirements file is "standalone"
                if [ $3 ]; then
                    envname=$3
                else
                    envname=`basename $reqfile`
                fi
                orb init $envname $reqfile
            fi
        else
            # either a name or a pip style url (hg+http://...@branch#egg=envname)
            shift
            url=`echo $1 | sed -n '/^\(hg\|git\|svn\)\+/p'`
            if [ $url ]; then
                eggname=`echo $url | sed "s/.*#egg=//g"`
                if [ ! $eggname ]; then
                    echo "ERROR: bad url - missing #egg=..."
                    exit 1
                else
                    if [ $2 ]; then
                        # user override of default env name
                        envname="$2"
                    else
                        envname=$eggname
                    fi
                    orb init $envname $3
                    cd "$envname.orb"
                    orb install -e $url
                    cd src/$eggname
                    if [ ! $3 ] && [ -f "REQUIREMENTS" ]; then
                        # no reqfile given but the default one is present
                        orb install -r REQUIREMENTS
                    fi
                    # if an envname was specified assume it's a branch name
                    if [ $2 ]; then
                        provider=`echo $url | sed "s/\+.*//g"`
                        if [ $provider = "git" ]; then
                            exists=`git branch | sed -n "/\b$envname\b/p" | sed "s/\s*//g"`
                            if [ $exists ]; then
                                if [ $exists = $envname ]; then
                                    # if not equality then it must be eg. '* master', so no need to check out
                                    git checkout $envname
                                fi
                            else
                                git checkout -b $envname
                            fi
                        fi
                    fi
                fi
            else
                reqfile=$2
                if [ ! $reqfile ] && [ -f "REQUIREMENTS" ]; then
                    orb init REQUIREMENTS $1
                    exit
                fi
                canonical_name $1
                fname="$orbname/.orb"
                echo $fname
                if [ ! -f $fname ]; then
                    echo ""
                    echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
                    echo " virtualenv $orbname --no-site-packages"
                    echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
                    echo ""
                    virtualenv $orbname --no-site-packages
                    touch $fname
                fi
                if [ ! -x "$orbname/bin/pip" ]; then
                    echo ""
                    echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
                    echo " $orbname/bin/easy_install pip"
                    echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
                    echo ""
                    $orbname/bin/easy_install pip
                fi
                if [ $reqfile ]; then
                    dir=`dirname $reqfile`
                    reqfile=`cd $dir;pwd`/`basename $reqfile`
                    if [ -f $reqfile ]; then
                        cd $orbname
                        orb install -r $reqfile
                        # system links, eg. lines like: #SYSTEM: PIL, psycopg2, mx
                        grep "^#SYSTEM: " $reqfile | sed "s/^#SYSTEM: //" | xargs orb link
                    fi
                fi
            fi
        fi
    fi
    ;;
"install")
    locate_environment
    shift
    if [ "$1" = "--help" ]; then
        # TODO: proper help message
        $envbindir/pip $@ | sed "s/Usage: pip/Usage: orb install/g"
        exit
    else
        echo ""
        echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
        echo " pip install $@"
        echo ":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::"
        echo ""
        $envbindir/pip install --download-cache=$cachedir "$@"
    fi
    ;;
"download")
    locate_environment
    shift
    if [ ! $1 ]; then
        echo "orb: ERROR - please specify a package to download"
        exit 1
    fi
    if [ ! $2 ]; then
        dest="."
    else
        dest="$2"
        if [ ! -d $dest ]; then
            echo "orb: ERROR - directory does not exist $dest"
            exit 1
        fi
    fi
    echo "orb: downloading $1"
    $envpip install $1 --download-cache=$cachedir --download=$dest
    ;;
"lib")
    locate_environment
    echo "$envlib"
    ;;
"ls")
    locate_environment
    #find $envdir/lib/python*/site-packages/* -maxdepth 0
    #for f in `find $envdir/lib/python*/site-packages/* -maxdepth 0 | sort`; do
    for f in `ls $envlib`; do
        fname=`basename $f`
        case $fname in
            *.pth)
                continue;;
            *.egg-info)
                continue;;
            *)
                echo $fname;;
        esac
    done
    ;;
link)
    # link to a system package or module
    # default python version is the orb's python
    locate_environment
    pyversion=`$envpython -c "import sys;print('%s.%s' % sys.version_info[:2])"`
    shift
    orb link$pyversion $@
;;
link?.?)
    locate_environment
    #ver=`echo "$1" | sed "s/link//g" | grep "^[2-3]\.[0-9]"`
    ver=`echo $1 | sed -n "s/link\([2-3]\.[0-9]\)/\1/p"`
    if [ ! $ver ]; then
        echo "invalid python version: "
        exit 1
    fi
    shift
    for m in $@; do
        m=`echo $m | sed "s/\.py$//g"`
        src=`python$ver -c "import $m;print($m.__file__)" | sed "s/\.pyc$/\.py/g" | sed "s/\/__init__\.py$//g"`
        if [ ! $src ]; then
            echo "not found: $m"
            exit 1
        fi
        dst="$envlib/`basename $src`"
        if [ ! -h $dst ]; then
            echo "linking $src"
            ln -s $src $dst
        fi
    done
;;
rm)
    # remove item from env site-packages
    locate_environment
    shift
    for m in $@; do
        rm -rf $envlib/$m*
    done
;;
home)
    locate_environment
    echo $envdir
;;
parent)
    cd `orb home`
    cd ..
    echo `pwd`
;;
"test")
    locate_environment
    shift
    $envbindir/nosetests --with-doctest "$@"
    ;;
"--help")
    usage
    ;;
"")
    usage
    ;;
*)
    locate_environment
    ext=`echo $1 | sed 's/.*\.//g'`
    if [ -f $1 ] && [ $ext = "py" ]; then
    #if [[ -f $1 && ${1: -3} -eq ".py" ]]; then
        $envbindir/python "$@"
    elif [ -f "$envbindir/$1" ]; then
        $envbindir/$@
    else
        #echo "activating environment $envdir"
        #. "$sourcefile"
        activate
        eval "$@"
        deactivate
    fi
    ;;
esac


