#!/bin/bash

# just in case PATH is not set correctly
PATH=".:./matrix_commander:../matrix_commander:$PATH"

# One may set similar values in the terminal before calling the script.
# export MC_OPTIONS="-d --room \!...some.room.id:matrix.example.org "

# getting some optional arguments
if [ "$MC_OPTIONS" != "" ]; then
    echo "Exellent. Variable MC_OPTIONS already set. " \
        "Using \"$MC_OPTIONS\" as additional options for testing."
else
    echo "Optionally, set variable \"MC_OPTIONS\" for further options."
fi

echo "Python version is: $(python --version)"
echo "GITHUB_WORKFLOW = $GITHUB_WORKFLOW"
echo "GITHUB_REPOSITORY = $GITHUB_REPOSITORY"
echo "MC_OPTIONS = $MC_OPTIONS"

if [[ "$GITHUB_WORKFLOW" != "" ]]; then # if in Github Action Workflow
    echo "I am in Github Action Workflow $GITHUB_WORKFLOW."
fi

failures=0

type eog >/dev/null 2>&1 || {
    echo "The test works better if you install 'eog'."
}

type convert >/dev/null 2>&1 || {
    echo "The test works better if you install 'convert' from ImageMagick."
}

function test1() {
    echo "=== Test 1: getting its own avatar ==="
    TMPFILE="test.png.tmp"
    rm -f "$TMPFILE"
    N=1
    mxc_urls=$(matrix-commander --get-avatar $MC_OPTIONS)
    if [[ "$mxc_urls" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    echo "$mxc_urls" # has the N URIs and URLs, like "mxc://...   https://..."
    for ii in $(seq $N); do
        echo "Handling avatar $ii"
        mxc_url=$(echo "$mxc_urls" | head -n $ii | tail -n 1)
        mxc="${mxc_url%    *}"  # before "    "
        url="${mxc_url##*    }" # after "    "
        echo "mxc is \"$mxc\""
        echo "url is \"$url\""
        wget "$url" -O "$TMPFILE"
        type eog >/dev/null 2>&1 && {
            echo "Let's look at the avatar."
            eog "$TMPFILE" >/dev/null 2>&1
        }
        rm -f "$TMPFILE"
    done
}

function test2() {
    echo "=== Test 2: getting the avatars of 2 users ==="
    user1=$(matrix-commander --whoami) # get some user_id
    if [[ "$user1" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    user2=$user1 # now we have 2 user ids
    TMPFILE="test.png.tmp"
    rm -f "$TMPFILE"
    N=2
    mxc_urls=$(matrix-commander --get-avatar "$user1" "$user2" $MC_OPTIONS)
    if [[ "$mxc_urls" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    echo "$mxc_urls" # has the N URIs and URLs, like "mxc://...   https://..."
    for ii in $(seq $N); do
        echo "Handling avatar $ii"
        mxc_url=$(echo "$mxc_urls" | head -n $ii | tail -n 1)
        mxc="${mxc_url%    *}"  # before "    "
        url="${mxc_url##*    }" # after "    "
        echo "    mxc is \"$mxc\""
        echo "    url is \"$url\""
        wget "$url" -O "$TMPFILE"
        echo "    Downloaded the avatar to \"$TMPFILE\"."
        ls -l "$TMPFILE"
        type eog >/dev/null 2>&1 && {
            echo "    Let's look at the avatar."
            eog "$TMPFILE" >/dev/null 2>&1
        }
        rm -f "$TMPFILE"
    done
}

function test3() {
    echo "=== Test 3: get the avatar, convert it to black-and-white, ==="
    echo "=== set the avatar to the new black-and-white one, ==="
    echo "=== set the avatar back to the original one. ==="

    TMPFILE="test.png.tmp"
    TMPFILEBW="test.png.bw.tmp"
    rm -f "$TMPFILE" "$TMPFILEBW"
    N=1
    mxc_urls=$(matrix-commander --get-avatar $MC_OPTIONS)
    if [[ "$mxc_urls" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    echo "$mxc_urls" # has the N URIs and URLs, like "mxc://...   https://..."
    for ii in $(seq $N); do
        echo "Handling avatar $ii"
        mxc_url=$(echo "$mxc_urls" | head -n $ii | tail -n 1)
        mxc="${mxc_url%    *}"  # before "    "
        url="${mxc_url##*    }" # after "    "
        echo "    mxc is \"$mxc\""
        echo "    url is \"$url\""
        wget "$url" -O "$TMPFILE"
        echo "    Downloaded the avatar to \"$TMPFILE\"."
        ls -l "$TMPFILE"
        type eog >/dev/null 2>&1 && {
            echo "    Let's look at the avatar."
            eog "$TMPFILE" >/dev/null 2>&1
        }
        convert "$TMPFILE" -colorspace Gray "$TMPFILEBW"
        type eog >/dev/null 2>&1 && {
            echo "    Let's look at the new black-and-white avatar."
            eog "$TMPFILEBW" >/dev/null 2>&1
        }
        # avatars must not be encrypted, use --plain
        mxc_key=$(matrix-commander --upload "$TMPFILEBW" --plain)
        if [[ "$mxc_key" == "" ]]; then
            echo "FAILURE."
            let failures++
            return
        fi
        mxcbw="${mxc_key%    *}" # before "    "
        echo "    Uploaded the new black-and-white avatar to URI \"$mxcbw\"."
        matrix-commander --set-avatar $mxcbw $MC_OPTIONS
        res="$?"
        if [ "$res" == "0" ]; then
            echo "SUCCESS."
        else
            echo "FAILURE."
            let failures++
        fi
        echo "    Setted the new avatar. Have a look at your client."
        read -t 30 -p "Like the new avatar?"
        matrix-commander --set-avatar $mxc $MC_OPTIONS
        res="$?"
        if [ "$res" == "0" ]; then
            echo "SUCCESS."
        else
            echo "FAILURE."
            let failures++
        fi
        echo "    Setted the avatar to as it was before. Have a look at your client."
        read -t 30 -p "Prefer the old avatar?"
        echo "" # add linebreak after timeout
        echo "    Done. We set it back to the original."
        rm -f "$TMPFILE" "$TMPFILEBW"
    done
}

function test4() {
    echo "=== Test 4: exporting keys to file ==="
    TMPFILE="test.keys.tmp"
    matrix-commander --export-keys "$TMPFILE" "bad-passphrase-3582" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS."
    else
        echo "FAILURE."
        let failures++
    fi
    echo "Here is the file with the exported keys:"
    ls -l "$TMPFILE"
}

function test5() {
    echo "=== Test 5: importing keys from file ==="
    TMPFILEBK="test.keys.bad.tmp"
    echo "bad key file" >"$TMPFILEBK"
    echo "This should fail because of bad keys file."
    matrix-commander --import-keys "$TMPFILEBK" "bad-passphrase-3582" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE."
        let failures++
    else
        echo "SUCCESS."
    fi
    echo "This should fail because of wrong passphrase."
    matrix-commander --import-keys "$TMPFILE" "wrong-passphrase" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE."
        let failures++
    else
        echo "SUCCESS."
    fi
    echo "This should work."
    # slow, many keys usually
    matrix-commander --import-keys "$TMPFILE" "bad-passphrase-3582" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS."
    else
        echo "FAILURE."
        let failures++
    fi
    rm -f "$TMPFILE" "$TMPFILEBK"
}

function test6() {
    echo "=== Test 6: getting its own user profile ==="
    N=1
    dispname_mxc_url_others=$(matrix-commander --get-profile $MC_OPTIONS)
    if [[ "$dispname_mxc_url_others" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    echo "$dispname_mxc_url_others" # lines with 4 pieces of information
    for ii in $(seq $N); do
        echo "Handling user profile $ii"
        dispname_mxc_url_other=$(echo "$dispname_mxc_url_others" | head -n $ii | tail -n 1)
        # shellcheck disable=SC2207
        out=($(grep -Eo '    |.+' <<<"$dispname_mxc_url_other")) # split by "    "
        dispname="${out[0]}"                                     # before first "    "
        mxc="${out[1]}"                                          # after first "    " and before 2nd "    "
        url="${out[2]}"
        other="${out[3]}"
        echo "    displayname is \"$dispname\""
        echo "    mxc is \"$mxc\""
        echo "    url is \"$url\""
        echo "    other info is \"$other\""
    done
}

function test7() {
    echo "=== Test 7: getting the user profiles of 2 users ==="
    user1=$(matrix-commander --whoami) # get some user_id
    if [[ "$user1" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    user2=$user1 # now we have 2 user ids
    N=2
    dispname_mxc_url_others=$(matrix-commander --get-profile "$user1" "$user2" $MC_OPTIONS)
    if [[ "$dispname_mxc_url_others" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    echo "$dispname_mxc_url_others" # lines with 4 pieces of information
    for ii in $(seq $N); do
        echo "Handling user profile $ii"
        dispname_mxc_url_other=$(echo "$dispname_mxc_url_others" | head -n $ii | tail -n 1)
        # dispname="$(sed -n "s/\(.*\)    \(mxc[^ ]*\)    \(http[^ ]*\)    \(.*\)/\1/p")"
        # shellcheck disable=SC2207
        out=($(grep -Eo '    |.+' <<<"$dispname_mxc_url_other")) # split by "    "
        dispname="${out[0]}"                                     # before first "    "
        mxc="${out[1]}"                                          # after first "    " and before 2nd "    "
        url="${out[2]}"
        other="${out[3]}"
        echo "    displayname is \"$dispname\""
        echo "    mxc is \"$mxc\""
        echo "    url is \"$url\""
        echo "    other info is \"$other\""
    done
}

function test8() {
    echo "=== Test 8: getting the state of default room ==="
    matrix-commander --room-get-state $MC_OPTIONS --output json | jq
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS."
    else
        echo "FAILURE."
        let failures++
    fi
}

function test9() {
    echo "=== Test 9: getting the visibility of default room ==="
    visi_room=$(matrix-commander --room-get-visibility $MC_OPTIONS)
    if [[ "$visi_room" == "" ]]; then
        echo "FAILURE."
        let failures++
        return
    fi
    visibility="${visi_room%    *}" # before "    "
    roomid="${visi_room##*    }"    # after "    "
    echo "    Visibility of room \"$roomid\" is \"$visibility\"."
}

function test10() {
    echo "=== Test 10: adding an alias to the default room ==="
    matrix-commander --room-set-alias $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE. The program should have failed, but didn't."
        let failures++
    else
        echo "SUCCESS. The program failed as expected."
    fi
}

function test11() {
    echo "=== Test 11: adding an alias to the default room ==="
    matrix-commander --room-set-alias a b c $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE. The program should have failed, but didn't."
        let failures++
    else
        echo "SUCCESS. The program failed as expected."
    fi
}

function test12() {
    echo "=== Test 12: adding an alias to the default room ==="
    matrix-commander --room-set-alias " spaces not allowed" r "wrong#" r "" r $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE. The program should have failed, but didn't."
        let failures++
    else
        echo "SUCCESS. The program failed as expected."
    fi
}

function test13() {
    echo "=== Test 13: adding an alias to the default room ==="
    matrix-commander --room-set-alias "Testing-room-A" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS. Alias set."
    else
        echo "FAILURE. Alias not set."
        let failures++
    fi
}

function test14() {
    echo "=== Test 14: adding an alias to the default room ==="
    matrix-commander --room-set-alias "Testing-room-B" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS. Alias set."
    else
        echo "FAILURE. Alias not set."
        let failures++
    fi
}

function test15() {
    echo "=== Test 15: resolving a room alias ==="
    matrix-commander --room-resolve-alias "doesntexist" "doesntexist2" "wrong#" " spa ce " "wrong:too" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE. The program should have failed, but didn't."
        let failures++
    else
        echo "SUCCESS. The program failed as expected."
    fi
}

function test16() {
    echo "=== Test 16: resolving a room alias ==="
    matrix-commander --room-resolve-alias "Testing-room-A" "Testing-room-B" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS. Aliases resolved."
    else
        echo "FAILURE. Aliases not resolved."
        let failures++
    fi
}

function test17() {
    echo "=== Test 17: deleting a room alias ==="
    matrix-commander --room-delete-alias "doesntexist" "doesntexist2" "wrong#" " spa ce " "wrong:too" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "FAILURE. The program should have failed, but didn't."
        let failures++
    else
        echo "SUCCESS. The program failed as expected."
    fi
}

function test18() {
    echo "=== Test 18: deleting a room alias ==="
    matrix-commander --room-delete-alias "Testing-room-A" "Testing-room-B" $MC_OPTIONS
    res="$?"
    if [ "$res" == "0" ]; then
        echo "SUCCESS. Alias deleted."
    else
        echo "FAILURE. Alias not deleted."
        let failures++
    fi
}

if [[ "$GITHUB_WORKFLOW" == "" ]]; then # skip in Github Action Workflow
    test1
    test2
    test3
fi
test4
test5
test6
test7
if [[ "$GITHUB_WORKFLOW" == "" ]]; then # skip in Github Action Workflow
    test8                               # uses jq
fi
test9
test10
test11
test12
test13
test14
test15
test16
test17
test18

echo "Finished test series with $failures failures."

exit $failures
