# add references to each interimap instance
sed -ri 's#^\[local\]$#&\nlist-reference = foo/#' "$XDG_CONFIG_HOME/interimap/config"
sed -ri 's#^\[local\]$#&\nlist-reference = bar/#' "$XDG_CONFIG_HOME/interimap/config2"
sed -ri 's#^\[local\]$#&\nlist-reference = baz/#' "$XDG_CONFIG_HOME/interimap/config3"

# create databases
interimap --config="config"
interimap --config="config2"
interimap --config="config3"

# start long-lived interimap processes
interimap --config="config"  --watch=1 & pid=$!
interimap --config="config2" --watch=1 & pid2=$!
interimap --config="config3" --watch=1 & pid3=$!

abort() {
    # kill interimap process and its children
    pkill -P "$pid" -TERM || true
    kill -TERM "$pid" || true
    pkill -P "$pid2" -TERM || true
    kill -TERM "$pid2" || true
    pkill -P "$pid3" -TERM || true
    kill -TERM "$pid3" || true
    wait
}
trap abort EXIT INT TERM


# mailbox list (as seen on local) and alphabet
declare -a mailboxes=( "INBOX" ) alphabet=()
str="#+-0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
for ((i=0; i < ${#str}; i++)); do
    alphabet[i]="${str:i:1}"
done

declare -a targets=( "local" "remote" "remote2" "remote3" )

timer=$(( $(date +%s) + 30 ))
while [ $(date +%s) -le $timer ]; do
    # create new mailbox with 10% probability
    if [ $(shuf -n1 -i0-9) -eq 0 ]; then
        u="$(shuf -n1 -e -- "${targets[@]}")" # choose target at random
        case "$u" in
            local) ns="$(shuf -n1 -e "foo/" "bar/" "baz/")";;
            remote) ns="foo/";;
            remote2) ns="bar/";;
            remote3) ns="baz/";;
            *) echo "Uh?" >&2; exit 1;;
        esac

        m=
        d=$(shuf -n1 -i1-3) # random depth
        for (( i=0; i < d; i++)); do
            l=$(shuf -n1 -i1-16)
            m="${m:+$m/}$(shuf -n "$l" -e -- "${alphabet[@]}" | tr -d '\n')"
        done
        mailboxes+=( "$ns$m" )
        case "$u" in
            local)   m="$ns$m";;
            remote)  m="${m//\//^}";;
            remote2) m="${m//\//\\}";;
            remote3) m="${m//\//\?}";;
            *) echo "Uh?" >&2; exit 1;;
        esac
        doveadm -u "$u" mailbox create -- "$m"
    fi

    # EXPUNGE some messages
    u="$(shuf -n1 -e -- "${targets[@]}")" # choose target at random
    n="$(shuf -n1 -i0-3)"
    while read guid uid; do
        doveadm -u "$u" expunge mailbox-guid "$guid" uid "$uid"
    done < <(doveadm -u "$u" search all | shuf -n "$n")

    # mark some existing messages as read (toggle \Seen flag as unlike other
    # flags it's easier to query and check_mailboxes_status checks it)
    u="$(shuf -n1 -e -- "${targets[@]}")" # choose target at random
    n="$(shuf -n1 -i0-9)"
    while read guid uid; do
        a="$(shuf -n1 -e add remove replace)"
        doveadm -u "$u" flags "$a" "\\Seen" mailbox-guid "$guid" uid "$uid"
    done < <(doveadm -u "$u" search all | shuf -n "$n")

    # select at random a mailbox where to deliver some messages
    u="$(shuf -n1 -e "local" "remote")" # choose target at random
    m="$(shuf -n1 -e -- "${mailboxes[@]}")"
    if [ "$u" = "remote" ]; then
        case "$m" in
            foo/*) u="remote";  m="${m#foo/}"; m="${m//\//^}";;
            bar/*) u="remote2"; m="${m#bar/}"; m="${m//\//\\}";;
            baz/*) u="remote3"; m="${m#baz/}"; m="${m//\//\?}";;
            INBOX) u="$(shuf -n1 -e "remote" "remote2" "remote3")";;
            *) echo "Uh? $m" >&2; exit 1;;
        esac
    fi

    # deliver between 1 and 5 messages to the chosen mailbox
    n="$(shuf -n1 -i1-5)"
    for (( i=0; i < n; i++)); do
        sample_message | deliver -u "$u"  -- -m "$m"
    done

    # sleep a little bit
    sleep "$(printf "0.%03d" "$(shuf -n1 -i1-999)")"
done

# wait a little longer so interimap has time to run loop() again and
# synchronize outstanding changes, then terminate the processes we
# started above
sleep 2

abort
trap - EXIT INT TERM

# check that the mailbox lists match
diff -u --label="local/mailboxes" --label="remote/mailboxes" \
    <( doveadm -u "local"  mailbox list | sed -n "s,^foo/,,p" | sort ) \
    <( doveadm -u "remote" mailbox list | tr '^' '/'          | sort )
diff -u --label="local/mailboxes" --label="remote2/mailboxes" \
    <( doveadm -u "local"   mailbox list | sed -n "s,^bar/,,p" | sort ) \
    <( doveadm -u "remote2" mailbox list | tr '\\' '/'         | sort )
diff -u --label="local/mailboxes" --label="remote3/mailboxes" \
    <( doveadm -u "local"   mailbox list | sed -n "s,^baz/,,p" | sort ) \
    <( doveadm -u "remote3" mailbox list | tr '?' '/'          | sort )

for m in "${mailboxes[@]}"; do
    case "$m" in
        foo/*) u="remote";  mb="${m#foo/}"; mr="${mb//\//^}";;
        bar/*) u="remote2"; mb="${m#bar/}"; mr="${mb//\//\\}";;
        baz/*) u="remote3"; mb="${m#baz/}"; mr="${mb//\//\?}";;
        INBOX) continue;;
        *) echo "Uh? $m" >&2; exit 1;;
    esac
    blob="x'$(printf "%s" "$mb" | tr "/" "\\0" | xxd -c256 -ps)'"
    check_mailbox_status2 "$blob" "$m" "$u" "$mr"
done

# vim: set filetype=sh :