#!/usr/bin/env bash

_LIBENV_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
LIMRISTEM_MAIL_CONFIG_DIR=${LIMRISTEM_MAIL_CONFIG_DIR:-"$(cd "$_LIBENV_DIR/.." && pwd)/config"}

limristem_mail_managed_group() {
  if getent group limristem-mail >/dev/null 2>&1; then
    printf 'limristem-mail\n'
  else
    printf 'root\n'
  fi
}

limristem_mail_prepare_managed_dir() {
  local dir=$1
  local group
  group=$(limristem_mail_managed_group)
  mkdir -p "$dir"
  case "$dir" in
    "$LIMRISTEM_MAIL_CONFIG_DIR"|"$LIMRISTEM_MAIL_CONFIG_DIR"/*|/etc/limristem-mail.d|/etc/limristem-mail.d/*) ;;
    *)
      return 0
      ;;
  esac
  chown root:"$group" "$dir" 2>/dev/null || true
  if [[ "$group" == "limristem-mail" ]]; then
    chmod 2770 "$dir" 2>/dev/null || true
  else
    chmod 0750 "$dir" 2>/dev/null || true
  fi
}

limristem_mail_install_managed_file() {
  local source_file=$1
  local target_file=$2
  local mode=${3:-0600}
  local group
  group=$(limristem_mail_managed_group)
  install -m "$mode" "$source_file" "$target_file"
  chown root:"$group" "$target_file" 2>/dev/null || true
}

limristem_mail_path_is_writable() {
  local path=$1
  local parent

  if [[ -e "$path" ]]; then
    [[ -w "$path" ]] || return 1
    parent=$(dirname "$path")
  else
    parent=$(dirname "$path")
  fi

  [[ -d "$parent" ]] || return 1

  local probe_file
  if ! probe_file=$(mktemp "$parent/.limristem-mail-write-test.XXXXXX" 2>/dev/null); then
    return 1
  fi
  rm -f "$probe_file"
}

limristem_mail_default_main_env_file() {
  printf '%s/limristem-mail.env\n' "$LIMRISTEM_MAIL_CONFIG_DIR"
}

limristem_mail_default_backup_env_file() {
  printf '%s/limristem-mail-backup.env\n' "$LIMRISTEM_MAIL_CONFIG_DIR"
}

limristem_mail_resolve_managed_config_dir() {
  local default_dir=${LIMRISTEM_MAIL_MANAGED_CONFIG_DIR:-$LIMRISTEM_MAIL_CONFIG_DIR}
  if limristem_mail_path_is_writable "$default_dir/.limristem-mail-managed-config-probe"; then
    printf '%s\n' "$default_dir"
  elif limristem_mail_path_is_writable /etc/limristem-mail.d/.limristem-mail-managed-config-probe; then
    printf '/etc/limristem-mail.d\n'
  else
    printf '%s\n' "$default_dir"
  fi
}

limristem_mail_resolve_main_env_file() {
  local default_file
  default_file=$(limristem_mail_default_main_env_file)

  if [[ -n "${LIMRISTEM_MAIL_ENV_FILE:-}" ]]; then
    printf '%s\n' "$LIMRISTEM_MAIL_ENV_FILE"
  elif limristem_mail_path_is_writable "$default_file"; then
    printf '%s\n' "$default_file"
  elif limristem_mail_path_is_writable /etc/limristem-mail.env; then
    printf '/etc/limristem-mail.env\n'
  else
    printf '%s\n' "$default_file"
  fi
}

limristem_mail_resolve_backup_env_file() {
  local default_file
  default_file=$(limristem_mail_default_backup_env_file)

  if [[ -n "${LIMRISTEM_MAIL_BACKUP_ENV_FILE:-}" ]]; then
    printf '%s\n' "$LIMRISTEM_MAIL_BACKUP_ENV_FILE"
  elif [[ "$(limristem_mail_resolve_main_env_file)" == "/etc/limristem-mail.env" ]] && limristem_mail_path_is_writable /etc/limristem-mail-backup.env; then
    printf '/etc/limristem-mail-backup.env\n'
  elif limristem_mail_path_is_writable "$default_file"; then
    printf '%s\n' "$default_file"
  elif limristem_mail_path_is_writable /etc/limristem-mail-backup.env; then
    printf '/etc/limristem-mail-backup.env\n'
  else
    printf '%s\n' "$default_file"
  fi
}

limristem_mail_resolve_rclone_config_file() {
  local main_env
  main_env=$(limristem_mail_resolve_main_env_file)
  if [[ "$main_env" == "/etc/limristem-mail.env" ]]; then
    printf '/etc/limristem-mail-rclone.conf\n'
  else
    printf '%s/rclone-backup.conf\n' "$LIMRISTEM_MAIL_CONFIG_DIR"
  fi
}

limristem_mail_env_quote() {
  local value=${1-}
  local backtick='`'
  value=${value//$'\n'/__LIMRISTEM_MAIL_ESCAPED_NL__}
  value=${value//$'\r'/__LIMRISTEM_MAIL_ESCAPED_CR__}
  value=${value//\\/\\\\}
  value=${value//\"/\\\"}
  value=${value//\$/\\$}
  value=${value//"$backtick"/\\$backtick}
  value=${value//__LIMRISTEM_MAIL_ESCAPED_NL__/\\n}
  value=${value//__LIMRISTEM_MAIL_ESCAPED_CR__/\\r}
  printf '"%s"' "$value"
}

limristem_mail_env_decode() {
  local value=${1-}
  local backtick='`'
  if [[ ${#value} -ge 2 && ${value:0:1} == '"' && ${value: -1} == '"' ]]; then
    value=${value:1:${#value}-2}
    value=${value//\\$backtick/$backtick}
    value=${value//\\\$/\$}
    value=${value//\\\"/\"}
    value=${value//\\r/__LIMRISTEM_MAIL_ESCAPED_CR__}
    value=${value//\\n/__LIMRISTEM_MAIL_ESCAPED_NL__}
    value=${value//\\\\/\\}
    value=${value//__LIMRISTEM_MAIL_ESCAPED_CR__/$'\r'}
    value=${value//__LIMRISTEM_MAIL_ESCAPED_NL__/$'\n'}
  elif [[ ${#value} -ge 2 && ${value:0:1} == "'" && ${value: -1} == "'" ]]; then
    value=${value:1:${#value}-2}
  fi
  printf '%s' "$value"
}

limristem_mail_env_write_var() {
  local key=$1
  local value=${2-}
  printf '%s=' "$key"
  limristem_mail_env_quote "$value"
  printf '\n'
}

limristem_mail_load_env_file() {
  local file=$1
  local line key value

  [[ -f "$file" ]] || return 0

  while IFS= read -r line || [[ -n "$line" ]]; do
    line=${line%$'\r'}
    [[ $line =~ ^[[:space:]]*# ]] && continue
    [[ $line =~ ^[[:space:]]*$ ]] && continue
    [[ $line =~ ^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]] || continue
    key=${BASH_REMATCH[1]}
    value=${BASH_REMATCH[2]}
    value=$(limristem_mail_env_decode "$value")
    printf -v "$key" '%s' "$value"
    # shellcheck disable=SC2163  # key intentionally contains the variable name to export.
    export "$key"
  done < "$file"
}

limristem_mail_upsert_env_value() {
  local file=$1
  local key=$2
  local value=${3-}
  local tmp_file found=no line

  limristem_mail_prepare_managed_dir "$(dirname "$file")"
  tmp_file=$(mktemp)
  if [[ -f "$file" ]]; then
    while IFS= read -r line || [[ -n "$line" ]]; do
      line=${line%$'\r'}
      if [[ $line == "$key="* ]]; then
        limristem_mail_env_write_var "$key" "$value" >> "$tmp_file"
        found=yes
      else
        printf '%s\n' "$line" >> "$tmp_file"
      fi
    done < "$file"
  fi
  if [[ "$found" != "yes" ]]; then
    limristem_mail_env_write_var "$key" "$value" >> "$tmp_file"
  fi
  limristem_mail_install_managed_file "$tmp_file" "$file" 0660
  rm -f "$tmp_file"
}

limristem_mail_normalize_env_file() {
  local file=$1
  local tmp_file line key value

  [[ -f "$file" ]] || return 0
  limristem_mail_path_is_writable "$file" || return 0

  tmp_file=$(mktemp)
  while IFS= read -r line || [[ -n "$line" ]]; do
    line=${line%$'\r'}
    if [[ $line =~ ^[[:space:]]*# ]] || [[ $line =~ ^[[:space:]]*$ ]]; then
      printf '%s\n' "$line" >> "$tmp_file"
      continue
    fi
    if [[ $line =~ ^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
      key=${BASH_REMATCH[1]}
      value=${BASH_REMATCH[2]}
      value=$(limristem_mail_env_decode "$value")
      limristem_mail_env_write_var "$key" "$value" >> "$tmp_file"
    else
      printf '%s\n' "$line" >> "$tmp_file"
    fi
  done < "$file"
  limristem_mail_install_managed_file "$tmp_file" "$file" 0660
  rm -f "$tmp_file"
}
