#!/usr/bin/env bash

. lib.bash || exit

url_size() {
	local url=$1
	size=$(curl -fsS --head "$url" |
		tr A-Z a-z |
		awk -F: '/^content-length:/ {print $2}' |
		tr -dc 0-9)
	echo $size
}

algo=""
name=""
size=-1
url=""
use_ext=0

while getopts ":125u:s:" OPT; do
	case $OPT in
	1) algo=SHA1;;
	2) algo=SHA256;;
	5) algo=MD5;;
	s) size=$OPTARG;;
	u) url=$OPTARG;;
	*) lib:die_getopts;;
	esac
done; shift $((OPTIND-1))

name=$1
hash=$2

if [[ $name == */* && ! $url ]]; then
	vmsg "name is a URL; automatically using basename"
	url=$name
	name=${url##*/}
fi

if [[ ! $algo ]]; then
	case ${#hash} in
		32)	algo=MD5;;
		40)	algo=SHA1;;
		64)	algo=SHA256;;
		*)	die "could not guess algorithm for given hash";;
	esac
	vmsg "guessing '$algo' as hash algorithm"
fi

algo=${algo^^}
hash=${hash,,}

case $algo in
	MD5)	hash_re='^[0-9a-f]{32}$';;
	SHA1)	hash_re='^[0-9a-f]{40}$';;
	SHA256)	hash_re='^[0-9a-f]{64}$';;
esac

if [[ ! $hash_re ]]; then
	die "unknown hash algorithm '$algo'"
elif [[ ! $hash =~ $hash_re ]]; then
	die "hash does not match the format for $algo"
fi

if [[ $url ]]; then
	# TODO: merge this mess into similar code above
	if [[ $url == */ || $url == *[?#]* ]]; then
		die "URL does not point to a file"
	fi
	name=$(basename "$url")
	size=$(url_size "$url")
fi

if (( size == -1 )); then
	warn "size (-s) was not specified"
fi

link=".git/annex/objects/"
link+="$algo"
if (( use_ext )); then
	link+="E"
fi
if (( size != -1 )); then
	link+="-s$size"
fi
link+="--$hash"
if (( use_ext )) && [[ $name == *.* ]]; then
	link+=".${name##*.}"
fi

ln -nsf "$link" "$name"
git annex add "$name"
git annex info "$name"

if [[ $url ]]; then
	info "registering annexed file URL"
	git annex addurl --file="$name" "$url"
fi
