#!/bin/sh

# gopm-lite
# a shell script to download, extract, and link
# dependencies from a .gopmfile
# requirements: curl, coreutils

# Needed environment variables:
# GOPATH - packages will be linked to $GOPATH/src/
# GOPMSTORE - where to store downloaded packages

# Optional environment variables
# MAXDEPTH - Maximum amount of attempts to recurse
#            and download all packages
# Defaults to 5

# Needed arguments:
# 1 - path to a .gopmfile

if [ -z "$GOPATH" -o -z "$GOPMSTORE" ]; then
    printf 'Need the following environment variables defined:\n'
    printf 'GOPATH\n'
    printf 'GOPMSTORE\n'
    exit 1
fi
if [ -z "$1" ]; then
    printf 'Usage: %s /path/to/.gopmfile\n' "$0"
    exit 1
fi

if [ -z "$MAXDEPTH" ]; then
    MAXDEPTH=5
fi

export MAXDEPTH
export GOPATH
export GOPMSTORE

mkdir -p "${GOPATH}/src"
mkdir -p "${GOPMSTORE}/archives"
mkdir -p "${GOPMSTORE}/repos"

indeps=""
curdepth=0

download_and_link() {
    local gopmfile=$1
    local extracted_counter=0
    printf 'Downloading deps for %s\n' "$gopmfile" 1>&2
    while read line; do
        if [ "$line" = "[deps]" ]; then
            indeps="deps"
            continue
        fi
        if [ -z "$line" -a -n "$indeps" ]; then
            break;
        fi
        if [ -z "$indeps" ]; then
            continue;
        fi

        host=""
        user=""
        package=""
        tagish=""

        url=$(printf '%s' "$line" | cut -f1 -d'=' | sed 's/ //g');
        version=$(printf '%s' "$line" | cut -f2 -d'=' | sed 's/ //g');

        host=$(printf '%s' "$url" | cut -f1 -d'/')
        user=$(printf '%s' "$url" | cut -f2 -d'/')
        package=$(printf '%s' "$url" | cut -f3 -d'/')

        if [ -z "$package" ]; then
            package="${user}"
        fi


        if [ "$host" = "gopkg.in" ]; then
            host="github.com"
            if [ "$user" = "$package" ]; then
                package=$(printf '%s' "$package" | cut -f1 -d'.')
                user="go-$package"
            else
                package=$(printf '%s' "$package" | cut -f1 -d'.')
            fi

        fi
        if [ "$host" = "golang.org" ]; then
            host="github.com"
            user="golang"
        fi

        if [ -n "$version" ]; then
            tagish=$(printf '%s' "$version" | cut -f2 -d':')
        else
            tagish="master"
        fi

        if [ ! -e "$GOPMSTORE/archives/$host-$user-$package-$tagish.tar.gz" ]; then
            curl --silent -R -L -o "$GOPMSTORE/archives/$host-$user-$package-$tagish.tar.gz" "https://$host/$user/$package/archive/$tagish.tar.gz"
        fi
        if [ ! -e "$GOPMSTORE/repos/$url.$tagish" ]; then
            mkdir -p "$GOPMSTORE/repos/$url.$tagish"
            tar xf "$GOPMSTORE/archives/$host-$user-$package-$tagish.tar.gz" -C "$GOPMSTORE/repos/$url.$tagish" --strip-components=1
        fi

        if [ ! -e "$GOPATH/src/$url" ]; then
            mkdir -p "$GOPATH/src/$url"
            rmdir "$GOPATH/src/$url"
            ln -s "$GOPMSTORE/repos/$url.$tagish" "$GOPATH/src/$url"
            extracted_counter=$((extracted_counter+1))
        fi

    done <"$gopmfile"
    printf '%s' "$extracted_counter"
}

packages_processed=$(download_and_link $1)
printf 'Done with %s packages\n' "$packages_processed" 1>&2
curdepth=1

export -f download_and_link

while [ ! "$packages_processed" = "0" ]; do
    if [ "$curdepth" = "$MAXDEPTH" ]; then
        break
    fi
    packages_processed=$(find -L "$GOPATH/src" -name '.gopmfile' -exec bash -c 'download_and_link "$0"' {} \; | awk '{s+=$1} END {print s}')
    curdepth=$((curdepth+1))
    printf 'Done with %s packages\n' "$packages_processed" 1>&2
done

exit 0
