#!/usr/bin/env bash
# Purpose: Update a maildir using m365 (Microsoft official CLI tool) and dovemail.
# - Email files are stored in ~/.local/share/mail
# - On first run, all email files are pulled.
# - On subsequent runs, only newer emails are pulled.
# - Limitation: emails moved or deleted from Outlook will *not* be deleted locally.


# Use a custom image for running m365 which has extra features --startTime and --endTime
# https://github.com/pnp/cli-microsoft365/pull/5875
function m365 () {
  podman run --rm \
    -v $HOME/.cli-m365-all-connections.json:/home/cli-microsoft365/.cli-m365-all-connections.json:ro \
    -v $HOME/.cli-m365-connection.json:/home/cli-microsoft365/.cli-m365-connection.json:ro \
    -v $HOME/.cli-m365-msal.json:/home/cli-microsoft365/.cli-m365-msal.json:ro \
    registry.gitlab.com/jennydaman/dovemail:m365-mathijsverbeeck-2af7199 \
    m365 "$@"
}

set -ex  # quit on error, print commands as they run

# get the outlook username
outlook_username="$(m365 status --query 'connectedAs' | jq -r)"

# maildir location
maildir="${XDG_DATA_HOME:-"$HOME/.local/share"}/mail/$outlook_username"

# on first run, create well-known mail folders
# ref: https://learn.microsoft.com/en-us/graph/api/resources/mailfolder?view=graph-rest-1.0
if ! [ -f "$maildir" ]; then
  WELL_KNOWN_FOLDERS=(Archive Drafts Inbox Outbox Scheduled Sentitems)
  for well_known_folder in "${WELL_KNOWN_FOLDERS[@]}"; do
    mkdir -vp "$maildir/$well_known_folder";
  done
fi

# for every subdirectory of the mail dir, pull new mail from that folder.
for folder_dir in "$maildir"/*/; do
  folder_name="$(basename "$folder_dir")"
  # create directories if necessary: cur, new, tmp
  mkdir -vp "${folder_dir}cur" "${folder_dir}new" "${folder_dir}tmp"

  # get the time of the most recently created file
  mtime_secs="$(find "$folder_dir" -type f -printf '%T@ %P\n' | sort -n | tail -n 1 | awk '{print $1}')"

  if [ -n "$mtime_secs" ]; then
    # pull new emails since most recently created email file
    # note: the --iso-8601 option of `date` is not compatible with m365
    start_time="$(date -d "@$mtime_secs" -u '+%Y-%m-%dT%H:%M:%SZ')"
    m365 outlook message list --folderName "$folder_name" --startTime "$start_time" | dovemail "${folder_dir}tmp"
  else
    # pull all emails
    m365 outlook message list --folderName "$folder_name" | dovemail "${folder_dir}tmp"
  fi
  # maildir spec says to download mail files to tmp, then move successfully downloaded files to new
  if [ -n "$(ls "${folder_dir}tmp")" ]; then
    mv "${folder_dir}tmp"/* "${folder_dir}new"
  fi
done
