#!/bin/bash
#
#  This file is part of TALER
#  Copyright (C) 2024 Taler Systems SA
#
#  TALER is free software; you can redistribute it and/or modify it under the
#  terms of the GNU General Public License as published by the Free Software
#  Foundation; either version 3, or (at your option) any later version.
#
#  TALER is distributed in the hope that it will be useful, but WITHOUT ANY
#  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
#  A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License along with
#  TALER; see the file COPYING.  If not, If not, see <http://www.gnu.org/license>
#

# Hard error reporting on.
set -eu


# Exit, with error message (hard failure)
function exit_fail() {
    echo " FAIL: " "$@" >&2
    EXIT_STATUS=1
    exit "$EXIT_STATUS"
}

CONF="$HOME/.config/taler-exchange.conf"
VERBOSE=0

while getopts 'ac:hirvV' OPTION;
do
    case "$OPTION" in
        a)
            # Address data is required.
            echo "ADDRESS_STREET_NAME"
            echo "ADDRESS_ZIPCODE"
            echo "ADDRESS_COUNTRY_CC"
            exit 0
            ;;
        c)
            # shellcheck disable=SC2034
            CONF="$OPTARG"
            ;;
        h)
            echo "This is a KYC measure program that sets up a measure to validate the address of the customer via Challenger."
            echo 'Supported options:'
            echo '  -a           -- show required attributes'
            # shellcheck disable=SC2016
            echo '  -c $CONF     -- set configuration'
            echo '  -h           -- print this help'
            echo '  -i           -- show required inputs'
            echo '  -r           -- show required context'
            echo '  -v           -- show version'
            echo '  -V           -- be verbose'
            exit 0
            ;;
        i)
            # Need context and current_rules.
            echo "attributes"
            echo "current_rules"
            exit 0
            ;;
        r)
            # Nothing needed from context
            exit 0
            ;;
        v)
            echo "$0 v0.0.0"
            exit 0
            ;;
        V)
            VERBOSE=1
            ;;
        ?)
        exit_fail "Unrecognized command line option"
        ;;
    esac
done

if [ 1 = "$VERBOSE" ]
then
    echo "Running $0" 1>&2
fi

# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlProgramInput
# for the full JSON with possible inputs.

# First, extract inputs we need
INPUTS=$(jq '{"current_rules":.current_rules,"attributes":.attributes}')

# Get address data
ADDRESS_NAME=$(echo "$INPUTS" | jq '.attributes.PERSON_FULL_NAME // .attributes.BUSINESS_DISPLAY_NAME // null')
# FIXME:
# Set 'name' to either of the two above, whichever one is non-null!

ADDRESS_STREET_NAME=$(echo "$INPUTS" | jq '.attributes.ADDRESS_STREET_NAME // .attributes.ADDRESS_BUILDING_NAME // null')
ADDRESS_STREET_NUMBER=$(echo "$INPUTS" | jq '.attributes.ADDRESS_STREET_NUMBER // .attributes.ADDRESS_BUILDING_NUMBER // null')
ADDRESS_LINES=$(echo "$INPUTS" | jq '.attributes.ADDRESS_LINES // null')
ADDRESS_ZIPCODE=$(echo "$INPUTS" | jq '.attributes.ADDRESS_ZIPCODE // null')
ADDRESS_TOWN=$(echo "$INPUTS" | jq '.attributes.ADDRESS_TOWN_DISTRICT // .attributes.ADDRESS_TOWN_LOCATION // null')
ADDRESS_COUNTRY_SUBDIVISION=$(echo "$INPUTS" | jq '.attributes.ADDRESS_COUNTRY_SUBDIVISION // null')
ADDRESS_COUNTRY_CC=$(echo "$INPUTS" | jq '.attributes.ADDRESS_COUNTRY_CC // null')

case "$ADDRESS_COUNTRY_CC"
in
    ch)
        COUNTRY="Switzerland"
        ;;
    de)
        COUNTRY="Germany"
        ;;
    fr)
        COUNTRY="France"
        ;;
    it)
        COUNTRY="Italy"
        ;;
    *)
        echo "ERROR: Country code '${ADDDRESS_COUNTRY_CC}' not recognized" 1>&2
        COUNTRY="${ADDRESS_COUNTRY_CC}"
        ;;
esac

# Convert address data to Challenger format as best we can.
ADDRESS=$(jq \
    --argjson full_name "$ADDRESS_NAME $ADDRESS_LINES" \
    --argjson street "$ADDRESS_STREET_NAME $ADDRESS_STREET_NUMBER" \
    --argjson city "$ADDRESS_TOWN" \
    --argjson postcode "$ADDRESS_ZIPCODE" \
    --argjson country "$COUNTRY" \
    '{"full_name":$full_name,"street":$street,"city":$city,"postcode":$postcode,"country":$country}')

# Get current rules.
CURRENT_RULES=$(echo "$INPUTS" | jq '.current_rules // null')
# Get context values.
EXPIRATION_TIME=$(echo "$INPUTS" | jq '.context.expiration_time // .current_rules.expiration_time // null')
# Preserve successor measure.
SUCCESSOR_MEASURE=$(echo "$INPUTS" | jq '.current_rules.successor_measure // null')

# Define custom measure for address validation
CUSTOM_MEASURES=$(jq \
    --argjson address "$ADDRESS" \
    '{"custom-address-investigation":{"context":{"initial_address":$address},"check_name":"postal-registration","prog_name":"inform-investigate","operation_type":"DEPOSIT"}}')

# Then trigger Challenger address check via oauth2, kyc-check-postal-registration
NEW_RULES=$(echo "$CURRENT_RULES" | jq '(.rules[] | select (.rule_name=="kyc-rule-deposit-limit-zero").measures=["custom-address-investigation"])' | jq --argjson cm "$CUSTOM_MEASURES" '.custom_measures=$cm')

# Finally, output the new rules.
# See https://docs.taler.net/taler-kyc-manual.html#tsref-type-AmlOutcome
# for the required output format.
jq \
    --argjson et "$EXPIRATION_TIME" \
    --argjson sm "$SUCCESSOR_MEASURE" \
    --argjson cm "$CUSTOM_MEASURES" \
    --argjson nr "$NEW_RULES" \
    '{"new_rules":$nr+{"expiration_time":$et,"successor_measure":$sm,"custom_measures":($nr.custom_measures+$cm)}}|del(..|nulls)'

exit 0
