#!/bin/sh
#xnecasr00 Roman Nečas
#9.3.2024

export POSIXLY_CORRECT=yes

# Function to display help message
print_help() {
    echo "Usage: xtf [-h|--help] [FILTER] [COMMAND] USER LOG [LOG2 ...]"
    echo ""
    echo "Options:"
    echo ""
    echo "  COMMAND can be one of these:"
    echo "    list          - displays records for the given user."
    echo "    list-currency - displays sorted list of currencies."
    echo "    status        - displays account status for the given user."
    echo "    profit        - calculates profit for the given user."
    echo ""
    echo "  FILTER can be a combination of:"
    echo "    -a DATETIME   - after: considers records after this date and time (exclusive)."
    echo "    -b DATETIME   - before: considers records before this date and time (exclusive)."
    echo "    -c CURRENCY   - considers records matching the given currency."
    echo ""
    echo "  -h or --help displays this help message."
}

# Function to display error message and exit with code 1
print_error() {
    echo "Error: $1" >&2
    exit 1
}

# Function to validate date
validate_date() {
    date -d "$1" >/dev/null 2>&1 || print_error "Invalid date: $1"
}

USER=""
LOGS=""
COMMAND=""
AFTER_DATE=""
BEFORE_DATE=""
CURRENCY_FILTER=""

# Process arguments
while [ "$#" -gt 0 ]; do
    case $1 in
        -h|--help)
            print_help
            exit 0
            ;;
        list|list-currency|status|profit)
            if [ -z "$COMMAND" ]; then
                COMMAND=$1
            else
                print_error "Multiple commands provided"
            fi
            ;;
        -a)
            validate_date "$2"
            AFTER_DATE=$2
            shift
            ;;
        -b)
            validate_date "$2"
            if [ -z "$BEFORE_DATE" ]; then
                BEFORE_DATE=$2
            else
                print_error "Multiple 'before' dates provided. Please provide only one 'before' date."
            fi
            shift
            ;;
        -c)
            CURRENCY_FILTER=$2
            shift
            ;;
        *)
            if [ -z "$USER" ]; then
                USER=$1
            else
                # Use a special character to separate log files
                LOGS="$LOGS|$1"
            fi
            ;;
    esac
    shift
done

# Set default command (list) if none specified
if [ -z "$COMMAND" ]; then
    COMMAND="list"
fi

# Check if user is specified
if [ -z "$USER" ]; then
    print_error "No user specified."
fi

# Change IFS to handle log files with spaces
OLD_IFS="$IFS"
IFS="|"

# Process logs
for LOG in $LOGS
do
    case "$LOG" in
        *.gz)
            zcat "$LOG" || print_error "Failed to read log: $LOG"
            ;;
        *)
            cat "$LOG" || print_error "Failed to read log: $LOG"
            ;;
    esac
done

# Restore IFS
IFS="$OLD_IFS"

# Filter records
awk -v user="$USER" -v after="$AFTER_DATE" -v before="$BEFORE_DATE" -v currency_filter="$CURRENCY_FILTER" '
    BEGIN {
        FS=";"
    }
    {
        if ($1 == "" || $2 !~ /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/ || $3 !~ /^[A-Z]{3}$/ || 
        $4 !~ /^-?[0-9]+\.[0-9]{4}$/) {
            print "Error: Invalid record format: " $0 > "/dev/stderr"
            exit 1
        }
    }
    $1 == user && ($2 > after || after == "") && ($2 < before || before == "") && ($3 ~ currency_filter || currency_filter == "") {
        print
    }
' |
# Process command
case "$COMMAND" in
    list)
        cat
        ;;
    list-currency)
        awk -F ";" '{print $3}' | sort -u
        ;;
    status)
        awk -F ";" '{ currency[$3] += $4 } END { for (cur in currency) { printf "%s : %.4f\n", cur, currency[cur] } }' | sort
        ;;
    profit)
    if [ -z "$XTF_PROFIT" ]; then
        XTF_PROFIT=20
    fi
    awk -v profit="$XTF_PROFIT" -F ";" '{ currency[$3] += $4 } END { for (cur in currency) { if (currency[cur] > 0) currency[cur] = 
    currency[cur] * (1 + profit / 100); printf "%s : %.4f\n", cur, currency[cur] } }' | sort
        ;;
esac

