#!/bin/sh
# xchg-rates
# Written in 2023 by Lucas
# CC0 1.0 Universal/Public domain - No rights reserved
#
# To the extent possible under law, the author(s) have dedicated all
# copyright and related and neighboring rights to this software to the
# public domain worldwide. This software is distributed without any
# warranty. You should have received a copy of the CC0 Public Domain
# Dedication along with this software. If not, see
# <http://creativecommons.org/publicdomain/zero/1.0/>.

usage()
{
	cat - <<EOF >&2
Usage:
	${0##*/} amount from to
	${0##*/} -l

Rates By Exchange Rate API - https://www.exchangerate-api.com
EOF
	exit 1
}

err()
{
	printf "%s: %s\n" "${0##*/}" "$*" >&2
	exit 1
}

warn()
{
	printf "%s: %s\n" "${0##*/}" "$*" >&2
}

date_gt()
{
	expr "X$1" ">" "X$2" >/dev/null
}

RATES_API=https://open.er-api.com/v6/latest/USD
fetch_rates()
{
	ftp -o "$RATES_JSON" "$RATES_API"
}

cachedir=${XDG_CACHE_HOME:-~/.cache}/xchg-rates
mkdir -p "$cachedir"

: ${RATES_JSON:=$cachedir/rates.json}

do_list=false
while getopts l flag; do
	case $flag in
	l)	do_list=true ;;
	*)	usage ;;
	esac
done
shift $(($OPTIND - 1))

if [ ! -f "$RATES_JSON" ]; then
	fetch_rates
fi

next_update_unix=$(jq -er .time_next_update_unix "$RATES_JSON")
if [ $? -ne 0 ]; then
	fetch_rates
else
	next_update=$(date -r "$next_update_unix" +%Y%m%dT%H%M%SZ)
	now=$(date +%Y%m%dT%H%M%SZ)
	if date_gt "$now" "$next_update"; then
		fetch_rates
	fi
fi

eol=$(jq -r '.time_eol_unix' "$RATES_JSON")
if [ X"$eol" != X"0" ]; then
	warn "EOL set for $(date -j "$eol" +%Y%m%dT%H%M%SZ)"
fi

if $do_list; then
	jq -r '.rates | to_entries | .[].key' "$RATES_JSON" | sort
	exit $?
fi

if [ $# -ne 3 ]; then
	usage
fi
amount=$1
from=$(echo "$2" | tr a-z A-Z)
to=$(echo "$3" | tr a-z A-Z)

if ! jq --arg k "$from" -er '.rates | has($k)' "$RATES_JSON" >/dev/null; then
	err "no rate for $from"
fi
if ! jq --arg k "$to" -er '.rates | has($k)' "$RATES_JSON" >/dev/null; then
	err "no rate for $to"
fi
jq -r --arg from "$from" --arg to "$to" \
    '.rates | [.[$from], .[$to]] | @tsv' "$RATES_JSON" | {
	read -r from to
	echo "$amount / $from * $to" | bc -l
}
