#!/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] [mailid]"
DEFAULT_MAX_LOG=9
DEFAULT_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_HOSTNAME)
EOF
}

MAILID=
# 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++))
                HOSTNAME="${!idx}"
            ;;
            *)
                if [[ -z "$MAILID" ]]; then
                    MAILID="$1"
                else
                    usage "Invalid parameter '$opt'"
                fi
        esac
        ((idx++))
    done
}
handle_args "$@"
[[ -z "$MAILID" ]] && usage
[[ "${MAX_LOG:-null}" == "null" ]] && MAX_LOG=$DEFAULT_MAX_LOG
[[ "${MAIL_LOG_PATH:-null}" == "null" ]] && MAIL_LOG_PATH=$POSTFIX_GENERAL_LOG_PATH
[[ "${HOSTNAME:-null}" == "null" ]] && HOSTNAME=$DEFAULT_HOSTNAME

function search_sender () {
    local mailid=$1 maillog=$2
    [ ! -f "$maillog" ] && maillog="$maillog.gz"
    [ -f "$maillog" ] && zgrep -F "$mailid" "$maillog" | grep -F 'from=' | \
        sed 's/^.* from=<\([^>]*\)>.*$/\1/' | head -n 1
}

function search_sender_from_mailid() {
    local mailid=$1
    debug "Search sender from Mail ID $mailid ..."
    res=$( search_sender "$mailid" "$MAIL_LOG_PATH" )
    if [ -n "$res" ]; then
        echo "$res"
        exit 0
    else
        debug "Not found from log file $MAIL_LOG_PATH. Try with archive (Max : $MAX_LOG)"
        for i in $( seq 1 "$MAX_LOG" ); do
            res=$( search_sender "$mailid" "$MAIL_LOG_PATH.$i" )
            if [ -n "$res" ]; then
                debug "Found from log file $MAIL_LOG_PATH.$i"
                echo "$res"
                exit 0
            else
                debug "Not found from log file $MAIL_LOG_PATH.$i"
            fi
        done
        debug "Not found in archive (Max : $MAX_LOG)"
    fi
}

if [ "$( run_other_tool eemailq --id "$MAILID" -O count )" -ne 0 ]; then
    debug "Mail $MAILID still in mailq. Try to detect original mail ID ..."
    ORIGMAILID=$(
        JUST_TRY=0 run_postfix_command postcat -qh "$MAILID" | grep -F "by $HOSTNAME" | \
            tail -n 1 | sed 's/^.*by .* with.* id \([A-Z0-9]*\).*$/\1/'
    )
    if [ -n "$ORIGMAILID" ]; then
        if [ "$ORIGMAILID" != "$MAILID" ]; then
            debug "Original mail ID : $ORIGMAILID"
            search_sender_from_mailid "$ORIGMAILID"
            debug "Sender not found from original mail ID"
            exit 1
        else
            debug "Mail ID and original mail ID are equals"
        fi
    else
        debug "Fail to detect original mail ID. Continue with mail ID in parameter"
    fi
fi

search_sender_from_mailid "$MAILID"
[ -n "$ORIGMAILID" ] && echo "Sender not found" && exit 1

debug "Sender not found. Try to detect original mail ID with message ID in log"

MSGID=$( JUST_TRY=0 run_other_tool mailid_to_messageid "$MAILID" )

if [ -z "$MSGID" ]; then
    debug "Message ID not found from log."
    exit 1
fi

debug "Message ID found : $MSGID. Try to detect original mail ID with this message ID"

ORIGMAILID=$( JUST_TRY=0 run_other_tool messageid_to_original_mailid "$MSGID" )

if [ -z "$ORIGMAILID" ]; then
    debug "Original mail ID not found from message ID"
    exit 1
fi

if [ "$ORIGMAILID" == "$MAILID" ]; then
    debug "Original mail ID is same as mail ID in parameter"
    exit 1
fi

search_sender_from_mailid "$ORIGMAILID"
debug "Sender not found from original mail ID"

exit 1
