#!/usr/bin/env sh
# runs mbsync, with pre-hooks and post-hooks
# by default, first runs imapfilter
# and after indexes with notmuch
#
# To run without invoking any hooks or retry attempts,
# run `checkmail raw`
# this will simply invoke a single isync run on all
# boxes with the correct config file set.
#
# for more advanced, per-account/channel hooks, see
# https://sourceforge.net/p/isync/feature-requests/8/

# available env vars:
# MBSYNC_MAX_TRIES=3
# MBSYNC_PRE="/bin/usr/cmd-to-run"
# MBSYNC_POST="/bin/usr/cmd-to-run"
# MBSYNC_NOTIFY=1

prehook() {
  if [ -n "$MBSYNC_PRE" ]; then
    eval "$MBSYNC_PRE"
    return 0
  fi
  imapfilter -c "${XDG_CONFIG_HOME:-/home/marty/.config}/imapfilter/config.lua"
}

posthook() {
  if [ -n "$MBSYNC_POST" ]; then
    eval "$MBSYNC_POST"
    return 0
  fi

  notmuch new 2>/dev/null
  afew --tag --new
  afew --move-mail --new
  afew --tag --new
  countnew
}

# use notmuch to index incoming mail and set the
# correct number of mails if new ones arrived for notifications
countnew() {
  num=$(notmuch count tag:unread and tag:inbox)
  HASMAIL="${num:-0}"
}

# fail the routine and optionally send a message why
fail() {
  [ -n "$1" ] && echo "$1"
  exit 1
}

checkmail() {
  mbsync -c "${XDG_CONFIG_HOME:-$HOME/.config}/isync/mbsyncrc" -a
}

checkonline() {
  # Ping 1.1.1.1 to confirm that we are on the internet
  ping -c 1 "1.1.1.1" >/dev/null 2>/dev/null || fail "checkmail can not access the internet."
}

# warn user that he has to enter his password in a moment
# to stop catching him offguard or entering something by accident
checkwarnuser() {
  agt=$(gpg2 --decrypt --no-tty --quiet --no-verbose --for-your-eyes-only --pinentry-mode cancel ~/.local/share/pass/misc/aerc-gmail-app-password.gpg 2>&1)
  if echo "$agt" | grep -qE 'No secret key'; then
    notify "Mail: Password phrase needed!"
    sleep 2.5
  fi
}

# send out a notification on new mail, to libnotify and stdout
notifymail() {
  [ "${MBSYNC_NOTIFY:-1}" -eq 0 ] && return

  if [ "${HASMAIL:-0}" -gt 0 ]; then
    notify "($HASMAIL) new mail"
  fi
}

notify() {
  command -v notify-send >/dev/null && notify-send "$@"
  echo "$@"
}

# Routine start

# check

# skip any retries and pre/post hooks, just run mbsync
if [ "$1" = "raw" ]; then
  checkmail
  exit
fi

main() {
  checkwarnuser

  prehook

  tries=0
  while true; do
    if checkmail; then
      break
    fi

    tries=$((tries + 1))
    if [ $tries -gt "${MBSYNC_MAX_TRIES:-3}" ]; then
      fail "maximum retries reached without success."
    fi
  done
  unset tries

  posthook

  notifymail
}

notmuch_foldertags() {
  notmuch tag +dump -inbox -deleted -- folder:Dump and not folder:Inbox
  notmuch tag +archived -inbox -deleted -- folder:Archive and not folder:Inbox
  notmuch tag +deleted -inbox -archived -- folder:Trash and not folder:Inbox
}

main