#!/usr/bin/env bash

# Favourites
curr='USD|EUR|GBP|JPY|UAH'

# Get HTML-table with currencies in RUB from Russian Central Bank page.
full_table="$(curl -sSL https://www.cbr.ru/currency_base/daily/ |
    sed "/<\/table>/,\$d" | tac | sed "/<table class/,\$d" | tac |
    dos2unix | tr '\n' ' ' | sed 's%>\s*<%><%g' | sed 's%</tbody>%%g' |
    sed 's%<tr>%\n%g;s%</tr>%%g' | sed 's%/%%g' |
    awk -F '<td>' '{print $2 " | " $4 " | " $6 " | " $8 " | " $10}')"

all_currencies_long() {
    echo "$full_table" |
        awk 'BEGIN {print "Цифр. код | Букв. код | Ед. | Валюта | Курс"}
        {print $0}' | column -t -s '|' | sed '2,3d'
}

all_currencies() {
    echo "$full_table" |
        awk -F '|' '{print $2 " " $3 " " $5}' | column -t
}

is_digit() {
    if [[ "$1" =~ [0-9]+ ]]; then
        return 0
    else
        return 1
    fi
}

is_currency() {
    if grep "^${1^^}$" <<< "$(all_currencies | awk '{print $1}')" > /dev/null; then
        return 0
    else
        return 1
    fi
}

available_currencies() {
    all_currencies | cut -d ' ' -f 1 | sort | tr '\n' ' '
}

calculate_rub() {
    _currency="$(all_currencies | grep "$currency" | awk '{print $3}' | sed 's%,%.%g')"
    _number="$(all_currencies | grep "$currency" | awk '{print $2}')"
    echo "(${_currency}/${_number})*${number}" | bc -l
}

while getopts iIlahv OPT; do
    case "$OPT" in
        i) noninteractive=1;;
        I) interactive=1;;
        l) long=1;;
        a) all=1;;
        h) echo -e 'Get currencies from Russian Central Bank and calculate.\n\n' \
            '\bUsage: currency [-iIlahv] [<currency>] [<number>]\n' \
            '\bOptions:\n' \
            '\b    -i     non-interactive mode.\n' \
            '\b    -I     interactive mode.\n' \
            '\b    -l     print currencies in long format.\n' \
            '\b    -a     print all currencies.\n' \
            '\b    -h     print this help message and exit..\n' \
            '\b    -v     print version and exit..\n\n' \
            "\bAvailable currencies: $(available_currencies)"
            exit 0;;
        v) echo 'currency 1.1'; exit 0;;
    esac
done

# Parse positional arguments.
shift $((OPTIND-1))

while (( "$#" )); do
    if is_currency "$1"; then
        currency="${1^^}"
    elif is_digit "$1"; then
        number="$1"
    else
        echo Invalid argument $1 >&2; exit 1
    fi
    shift
done

if [ "$currency" ] && [ "$number" ]; then
    calculate_rub
    exit "$?"
fi

if [ ! "$interactive" ]; then
    # Show currencies table
    if [ "$long" ]; then
        all_currencies_long | head -n 1
        if [ "$all" ]; then
            all_currencies_long | sed '1d'
        else
            all_currencies_long | grep -E "$curr"
        fi
    else
        if [ "$all" ]; then
            all_currencies
        else
            all_currencies | grep -E "$curr"
        fi
    fi

    if [ "$noninteractive" ]; then
        exit 0
    else
        echo
    fi
fi

# Interactive mode
echo 'Specify currency and c.u. (^C for exit):'
while true; do
    if [ "$currency" ]; then
        echo -n ">>> (${currency^^}) "
        read number
        if is_currency "$number"; then
            currency="${number^^}"; unset number
        elif ! is_digit "$number"; then
            echo Invalid number $number; unset number
        fi
    else
        echo -n ">>> "
        read currency
        if is_currency "$currency"; then
            currency="${currency^^}"
        else
            echo Invalid currency $currency; unset currency
        fi
    fi

    if [ "$number" ]; then
        calculate_rub
    fi
done
