#!/usr/bin/env bash

###############################################################################
# This script restores `mtime` attributes based on the `Date` header of message
# Requirements : bash 3.x, GNU coreutils (5.x+ ?)
# Version      : 1.1
# Maintainer   : Aleksandr Bashurov
#########

export LANG=C
export LC_ALL=C

###########################################################
# Function `set_globals()`
# Updates the globals that are used in the script
# Input   : None
# Output  : None
# Globals : +MAIL_D, +UPDATED_BEFORE, +VERBOSE
set_globals() {
  MAIL_D="/var/qmail/mailnames/"
  UPDATED_BEFORE="2"
# VERBOSE="true"
}

###########################################################
# Function `err()`
# Echoes to the `stderr` and finishes script execution
# Input   : $* any number of strings (will be concatenated)
# Output  : None
# Globals : None
err() {
  echo -ne "\\e[31mERROR\\e[m:" >&2
  echo " $*" >&2
  exit 1
}

###########################################################
# Function `warn()`
# Echoes to the `stderr` and continues script execution
# Input   : $* any number of strings (will be concatenated)
# Output  : None
# Globals : None
warn() {
  echo -ne "\\e[33mWARNING\\e[m:" >&2
  echo " $*" >&2
}

###########################################################
# Function `info()`
# Echoes to the `stderr` if VERBOSE variable exists
# Input   : $* any number of strings (will be concatenated)
# Output  : None
# Globals : VERBOSE
info() {
  if [[ -n ${VERBOSE+x} ]]; then
    echo -ne "\\e[33mINFO\\e[m:" >&2
    echo " $*" >&2
  fi
}

###########################################################
# Function `process_mailname()`
# Finds all applicable messages and updates mtimes
# Input   : $1 string (mailname as example@example.com)
# Output  : None
# Globals : MAIL_D, UPDATED_BEFORE
process_mailname() {
  local full_mailname="$1" domain user
  if [[ $full_mailname == *"@"* ]]; then
    user="$(cut -d'@' -f1 <<<"$full_mailname")"
    domain="$(cut -d'@' -f2 <<<"$full_mailname")"
    if [[ -d ${MAIL_D}/${domain}/${user}/Maildir/ ]]; then
      find "${MAIL_D}/${domain}/${user}/Maildir/" -type f \
        -mtime "-${UPDATED_BEFORE}" -print0 | while IFS= read -rd '' file; do
          update_mtimes "$file"
        done
    else
      warn "Maildir \"${MAIL_D}/${domain}/${user}/Maildir/\" " \
        "does not exist, skipping"
    fi
  else
    warn "Specified mailname " \
    "\"${full_mailname}\" could not be validated, skipping"
  fi
}

###########################################################
# Function `update_mtimes()`
# Updates mtimes of the provided file with extracted `Date`
# Input   : $1 string full path to file
# Output  : None
# Globals : None
update_mtimes() {
  local file="$1"
  date="$(grep -m1 '^Date' "$file" | cut -d' ' -f2-)"
  if [[ -n $date ]]; then
    if date -d "$date"; then
      touch -c --date="$date" "$file"
      echo "Set date ${date} on ${file}"
    else
      info "Could not parse date, skipping ${file}"
    fi
  else
    info "Could not extract date, skipping ${file}"
  fi
}

###########################################################
# Function `main()`
# Processes over mailnames and updates mtimes
# Input   : $@ array (Initial args)
# Output  : None
# Globals : None
main() {
  set_globals
  for mailname in "$@"; do
    process_mailname "$mailname"
  done
}

main "$@"

