#!/bin/bash
# vim: shiftwidth=4 tabstop=4 expandtab

LIB_DIR="$( realpath "$( dirname "$( realpath "$0" )" )/../lib/ee-postfix-tools" )"
if [[ -e "$LIB_DIR/common" ]]; then
    # shellcheck source=/dev/null
    source "$LIB_DIR/common"
else
    echo "Failed to load ee-postfix-tools common lib"
    exit 1
fi

# shellcheck disable=SC2034
EXTRA_SHORT_USAGE="[-m X] [-l /path/to/mail.log] [username]"
DEFAULT_MAX_LOG=9
DEFAULT_SMTPD_HOSTNAME=$( hostname -f )

# shellcheck disable=SC2317,SC2329
function extra_usage() {
    cat << EOF
    -l|--log-path /path/to/mail.log  Postfix mail log path to look in
                                     (default: $POSTFIX_GENERAL_LOG_PATH)
    -m|--max-log X                   Max log files to look in (default: $DEFAULT_MAX_LOG)
    -H|--hostname [hostname]         Mail host's hostname (default: $DEFAULT_SMTPD_HOSTNAME)
EOF
}

USERNAME=
# shellcheck disable=SC2317,SC2329
function handle_extra_args() {
    local idx=1 opt
    while [[ $idx -le $# ]]; do
        opt=${!idx}
        case "$opt" in
            -l|--log-path)
                ((idx++))
                MAIL_LOG_PATH="${!idx}"
                [[ -e "$MAIL_LOG_PATH" ]] || usage "$MAIL_LOG_PATH not found"
            ;;
            -m|--max-log)
                ((idx++))
                MAX_LOG="${!idx}"
                check_int "$MAX_LOG" 1 || \
                    usage "Invalid max log specified: must be an integer >= 1"
            ;;
            -H|--hostname)
                ((idx++))
                SMTPD_HOSTNAME="${!idx}"
            ;;
            *)
                if [[ -z "$USERNAME" ]]; then
                    USERNAME="$opt"
                else
                    usage "Invalid parameter '$opt'"
                fi
        esac
        ((idx++))
    done
}
handle_args "$@"
[[ -z "$USERNAME" ]] && usage
[[ "${MAX_LOG:-null}" == "null" ]] && MAX_LOG=$DEFAULT_MAX_LOG
[[ "${MAIL_LOG_PATH:-null}" == "null" ]] && MAIL_LOG_PATH=$POSTFIX_GENERAL_LOG_PATH
[[ "${SMTPD_HOSTNAME:-null}" == "null" ]] && SMTPD_HOSTNAME=$DEFAULT_SMTPD_HOSTNAME

info "List emails in deferred Postfix queue..."
mapfile -t deferred_mails_ids < <( run_other_tool eemailq --state deferred --output-data id )
info "${#deferred_mails_ids[@]} email(s) found in deferred Postfix queue"

info "Compute mail ID to deferred mail ID mapping..."
declare -A original_id_to_ids
for id in "${deferred_mails_ids[@]}"; do
    mapfile -t deferred_mail_ids < <(
        JUST_TRY=0 run_postfix_command postcat -qh "$id" | \
            grep -E "\sby $SMTPD_HOSTNAME .* id [A-Z0-9]+;?\$" | \
            sed 's/.* id \([A-Z0-9]\+\);\?$/\1/'
    )
    debug "${#deferred_mail_ids[@]} mail IDs found for email $id: ${deferred_mail_ids[*]}"
    for mid in "${deferred_mail_ids[@]}"; do
        original_id_to_ids[$mid]="$id"
    done
done

info "Search for email original IDs of user $USERNAME in mail log (and $MAX_LOG previous ones)..."
mapfile -t user_mails_ids < <(
    JUST_TRY=0 run_other_tool username_to_original_mailid \
        -l "$MAIL_LOG_PATH" -m "$MAX_LOG" "$USERNAME"
)
info "${#user_mails_ids[@]} mail IDs found for user $USERNAME"

info "Looking for deferred emails of user $USERNAME..."
result=()
for id in "${user_mails_ids[@]}"; do
    if [[ "${original_id_to_ids[$id]:-null}" != "null" ]]; then
        debug "Deferred mail ID found for original ID $id: ${original_id_to_ids[$id]}"
        result+=( "${original_id_to_ids[$id]}" )
    else
        debug "No deferred mail ID found for original ID $id"
    fi
done
info "${#result[@]} deferred mail(s) of user $USERNAME found"
implode $'\n' "${result[@]}"
