#!/bin/bash

APP_DIR="/opt/r7-office/organizer"
APP_BIN="${APP_DIR}/r7organizer"
PROFILE_ROOT="${HOME}/.r7organizer"
STARTUP_CACHE_STAMP="${PROFILE_ROOT}/.r7organizer-startupcache.stamp"
SESSION_MARKER="${PROFILE_ROOT}/.r7organizer-session-active"
UNCLEAN_EXIT_COUNT_FILE="${PROFILE_ROOT}/.r7organizer-unclean-exit-count"
STARTUP_CACHE_FORCE_FLAG_NAME=".r7exchange-force-startupcache-reset"
STARTUP_LOGIN_SUPPRESS_FLAG_NAME=".r7exchange-skip-startup-login-once"
ATTACHMENT_STAGE_DIR="${PROFILE_ROOT}/.r7organizer-mail-attachments"
WRAPPER_DEBUG_LOG="${PROFILE_ROOT}/.r7organizer-wrapper-debug.log"
WRAPPER_DEBUG_ENABLED=0

case "${R7_WRAPPER_DEBUG:-}" in
  1|true|TRUE|yes|YES|on|ON)
    WRAPPER_DEBUG_ENABLED=1
    ;;
esac

uri_decode() {
  local value="$1"
  value="${value//+/ }"
  printf '%b' "${value//%/\\x}"
}

debug_log() {
  if [ "$WRAPPER_DEBUG_ENABLED" != "1" ]; then
    return 0
  fi

  local now=""
  now="$(date '+%Y-%m-%d %H:%M:%S' 2>/dev/null || true)"
  mkdir -p "$PROFILE_ROOT" 2>/dev/null || true
  printf '[%s] %s\n' "$now" "$*" >> "$WRAPPER_DEBUG_LOG" 2>/dev/null || true
}

debug_log_args() {
  if [ "$WRAPPER_DEBUG_ENABLED" != "1" ]; then
    return 0
  fi

  local label="$1"
  shift
  local rendered=""
  local arg=""

  for arg in "$@"; do
    if [ -n "$rendered" ]; then
      rendered="${rendered} "
    fi
    rendered="${rendered}$(printf '%q' "$arg")"
  done

  debug_log "${label}: ${rendered}"
}

normalize_attachment_path() {
  local value="$1"

  case "$value" in
    file://localhost/*)
      value="/${value#file://localhost/}"
      value="$(uri_decode "$value")"
      ;;
    file:///*)
      value="/${value#file:///}"
      value="$(uri_decode "$value")"
      ;;
  esac

  printf '%s' "$value"
}

escape_compose_value() {
  local value="$1"
  value="${value//\'/%27}"
  value="${value//\"/%22}"
  printf '%s' "$value"
}

join_by_comma() {
  local result=""
  local item=""

  for item in "$@"; do
    if [ -z "$item" ]; then
      continue
    fi
    if [ -n "$result" ]; then
      result="${result},${item}"
    else
      result="$item"
    fi
  done

  printf '%s' "$result"
}

append_compose_field() {
  local key="$1"
  local value="$2"

  if [ -z "$value" ]; then
    return 0
  fi

  XDG_COMPOSE_FIELDS+=("${key}='$(escape_compose_value "$value")'")
}

cleanup_staged_attachment_files() {
  if [ ! -d "$ATTACHMENT_STAGE_DIR" ]; then
    return 0
  fi

  find "$ATTACHMENT_STAGE_DIR" -type f -mtime +2 -delete 2>/dev/null || true
}

stage_attachment_file() {
  local source="$1"
  local normalized_source=""
  local staged_path=""
  local base_name=""

  normalized_source="$(normalize_attachment_path "$source")"
  if [ -z "$normalized_source" ] || [ ! -f "$normalized_source" ]; then
    debug_log "stage_attachment_file: source_missing original=$(printf '%q' "$source") normalized=$(printf '%q' "$normalized_source")"
    printf '%s' "$source"
    return 0
  fi

  case "$normalized_source" in
    "${ATTACHMENT_STAGE_DIR}"/*)
      debug_log "stage_attachment_file: already_staged $(printf '%q' "$normalized_source")"
      printf '%s' "$normalized_source"
      return 0
      ;;
  esac

  mkdir -p "$ATTACHMENT_STAGE_DIR" 2>/dev/null || true
  base_name="$(basename "$normalized_source")"
  staged_path="${ATTACHMENT_STAGE_DIR}/$(date +%s)-$$-${base_name}"

  if cp -f -- "$normalized_source" "$staged_path" 2>/dev/null; then
    debug_log "stage_attachment_file: copied $(printf '%q' "$normalized_source") -> $(printf '%q' "$staged_path")"
    printf '%s' "$staged_path"
    return 0
  fi

  debug_log "stage_attachment_file: copy_failed using_original=$(printf '%q' "$normalized_source")"
  printf '%s' "$normalized_source"
}

stage_attachment_references_in_string() {
  local input="$1"
  local updated="$1"
  local match=""
  local key=""
  local source=""
  local staged=""
  local escaped_staged=""
  local placeholder_key=""
  local replacement=""
  local lowered_input=""

  lowered_input="$(printf '%s' "$input" | tr '[:upper:]' '[:lower:]')"
  if [[ "$lowered_input" == mailto:* ]]; then
    printf '%s' "$input"
    return 0
  fi

  while [[ "$updated" =~ (attachment|attach)=\'([^\']*)\' ]]; do
    match="${BASH_REMATCH[0]}"
    key="${BASH_REMATCH[1]}"
    source="${BASH_REMATCH[2]}"
    staged="$(stage_attachment_file "$source")"
    escaped_staged="$(escape_compose_value "$staged")"
    placeholder_key="__${key}_staged__"
    replacement="${placeholder_key}='${escaped_staged}'"
    updated="${updated/$match/$replacement}"
  done

  while [[ "$updated" =~ (attachment|attach)=\"([^\"]*)\" ]]; do
    match="${BASH_REMATCH[0]}"
    key="${BASH_REMATCH[1]}"
    source="${BASH_REMATCH[2]}"
    staged="$(stage_attachment_file "$source")"
    escaped_staged="$(escape_compose_value "$staged")"
    placeholder_key="__${key}_staged__"
    replacement="${placeholder_key}=\"${escaped_staged}\""
    updated="${updated/$match/$replacement}"
  done

  while [[ "$updated" =~ (attachment|attach)=([^,\)]*) ]]; do
    match="${BASH_REMATCH[0]}"
    key="${BASH_REMATCH[1]}"
    source="${BASH_REMATCH[2]}"
    staged="$(stage_attachment_file "$source")"
    escaped_staged="$(escape_compose_value "$staged")"
    placeholder_key="__${key}_staged__"
    replacement="${placeholder_key}=${escaped_staged}"
    updated="${updated/$match/$replacement}"
  done

  updated="${updated//__attachment_staged__/attachment}"
  updated="${updated//__attach_staged__/attach}"

  printf '%s' "$updated"
}

parse_mailto_argument() {
  local uri="$1"
  local address_part="${uri#mailto:}"
  local query_part=""
  local pair=""
  local key=""
  local value=""

  if [ "$address_part" != "${address_part#*\?}" ]; then
    query_part="${address_part#*\?}"
    address_part="${address_part%%\?*}"
  fi

  address_part="$(uri_decode "$address_part")"
  if [ -n "$address_part" ]; then
    XDG_TO_VALUES+=("$address_part")
  fi

  if [ -z "$query_part" ]; then
    return 0
  fi

  local old_ifs="$IFS"
  IFS='&'
  for pair in $query_part; do
    key="${pair%%=*}"
    if [ "$pair" = "$key" ]; then
      value=""
    else
      value="${pair#*=}"
    fi
    key="$(printf '%s' "$key" | tr '[:upper:]' '[:lower:]')"
    value="$(uri_decode "$value")"
    case "$key" in
      to)
        XDG_TO_VALUES+=("$value")
        ;;
      cc)
        XDG_CC_VALUES+=("$value")
        ;;
      bcc)
        XDG_BCC_VALUES+=("$value")
        ;;
      subject)
        if [ -z "$XDG_SUBJECT" ]; then
          XDG_SUBJECT="$value"
        fi
        ;;
      body)
        if [ -z "$XDG_BODY" ]; then
          XDG_BODY="$value"
        fi
        ;;
      attach|attachment)
        XDG_ATTACHMENTS+=("$value")
        ;;
    esac
  done
  IFS="$old_ifs"
}

should_translate_xdg_email_args() {
  local arg=""
  local seen_mailto=0
  local count="$#"
  local lowered_arg=""

  for arg in "$@"; do
    lowered_arg="$(printf '%s' "$arg" | tr '[:upper:]' '[:lower:]')"
    case "$arg" in
      --attach|--attachment|--attach=*|--attachment=*|--subject|--subject=*|--body|--body=*|--cc|--cc=*|--bcc|--bcc=*|--utf8)
        return 0
        ;;
      mailto:*)
        if [[ "$lowered_arg" == *'?attach='* ]] ||
           [[ "$lowered_arg" == *'&attach='* ]] ||
           [[ "$lowered_arg" == *'?attachment='* ]] ||
           [[ "$lowered_arg" == *'&attachment='* ]]; then
          return 0
        fi
        seen_mailto=1
        ;;
    esac
  done

  if [ "$seen_mailto" = "1" ] && [ "$count" -gt 1 ]; then
    return 0
  fi

  return 1
}

translate_xdg_email_args() {
  local arg=""
  local next_arg=""
  local compose_value=""
  local attachment_path=""
  local normalized_arg=""
  local staged_attachments=()
  local saw_mailto=0

  XDG_TO_VALUES=()
  XDG_CC_VALUES=()
  XDG_BCC_VALUES=()
  XDG_ATTACHMENTS=()
  XDG_SUBJECT=""
  XDG_BODY=""
  XDG_COMPOSE_FIELDS=()

  while [ "$#" -gt 0 ]; do
    arg="$1"
    case "$arg" in
      --attach|--attachment)
        if [ "$#" -ge 2 ]; then
          XDG_ATTACHMENTS+=("$2")
          shift 2
          continue
        fi
        shift
        continue
        ;;
      --attach=*|--attachment=*)
        XDG_ATTACHMENTS+=("${arg#*=}")
        shift
        continue
        ;;
      --subject)
        if [ "$#" -ge 2 ]; then
          XDG_SUBJECT="$2"
          shift 2
          continue
        fi
        shift
        continue
        ;;
      --subject=*)
        XDG_SUBJECT="${arg#*=}"
        shift
        continue
        ;;
      --body)
        if [ "$#" -ge 2 ]; then
          XDG_BODY="$2"
          shift 2
          continue
        fi
        shift
        continue
        ;;
      --body=*)
        XDG_BODY="${arg#*=}"
        shift
        continue
        ;;
      --cc)
        if [ "$#" -ge 2 ]; then
          XDG_CC_VALUES+=("$2")
          shift 2
          continue
        fi
        shift
        continue
        ;;
      --cc=*)
        XDG_CC_VALUES+=("${arg#*=}")
        shift
        continue
        ;;
      --bcc)
        if [ "$#" -ge 2 ]; then
          XDG_BCC_VALUES+=("$2")
          shift 2
          continue
        fi
        shift
        continue
        ;;
      --bcc=*)
        XDG_BCC_VALUES+=("${arg#*=}")
        shift
        continue
        ;;
      --utf8)
        shift
        continue
        ;;
      mailto:*)
        saw_mailto=1
        parse_mailto_argument "$arg"
        shift
        continue
        ;;
      --*)
        if [ "$#" -ge 2 ]; then
          next_arg="$2"
          if [ "${next_arg#-}" != "$next_arg" ]; then
            shift
          else
            shift 2
          fi
        else
          shift
        fi
        continue
        ;;
      *)
        normalized_arg="$(normalize_attachment_path "$arg")"
        if [ -n "$normalized_arg" ] && [ -f "$normalized_arg" ]; then
          XDG_ATTACHMENTS+=("$normalized_arg")
        elif [ -n "$arg" ] && [ "$saw_mailto" = "1" ] && [[ "$arg" == file://* ]]; then
          XDG_ATTACHMENTS+=("$arg")
        elif [ -n "$arg" ]; then
          XDG_TO_VALUES+=("$arg")
        fi
        shift
        continue
        ;;
    esac
  done

  cleanup_staged_attachment_files
  for attachment_path in "${XDG_ATTACHMENTS[@]}"; do
    staged_attachments+=("$(stage_attachment_file "$attachment_path")")
  done

  append_compose_field "to" "$(join_by_comma "${XDG_TO_VALUES[@]}")"
  append_compose_field "cc" "$(join_by_comma "${XDG_CC_VALUES[@]}")"
  append_compose_field "bcc" "$(join_by_comma "${XDG_BCC_VALUES[@]}")"
  append_compose_field "subject" "$XDG_SUBJECT"
  append_compose_field "body" "$XDG_BODY"
  append_compose_field "attachment" "$(join_by_comma "${staged_attachments[@]}")"

  compose_value="$(join_by_comma "${XDG_COMPOSE_FIELDS[@]}")"
  if [ -z "$compose_value" ]; then
    return 1
  fi

  TRANSLATED_APP_ARGS=(-compose "$compose_value")
  return 0
}

append_attachment_to_compose_value() {
  local compose_value="$1"
  local attachment_csv="$2"
  local escaped_csv=""

  if [ -z "$attachment_csv" ]; then
    printf '%s' "$compose_value"
    return 0
  fi

  if [[ "$compose_value" == *"attachment="* ]] || [[ "$compose_value" == *"attach="* ]]; then
    printf '%s' "$compose_value"
    return 0
  fi

  escaped_csv="$(escape_compose_value "$attachment_csv")"
  if [ -z "$compose_value" ]; then
    printf "attachment='%s'" "$escaped_csv"
    return 0
  fi

  printf "%s,attachment='%s'" "$compose_value" "$escaped_csv"
}

append_attachment_to_remote_value() {
  local remote_value="$1"
  local attachment_csv="$2"
  local escaped_csv=""

  if [ -z "$attachment_csv" ]; then
    printf '%s' "$remote_value"
    return 0
  fi

  if [[ "$remote_value" == *"attachment="* ]] || [[ "$remote_value" == *"attach="* ]]; then
    printf '%s' "$remote_value"
    return 0
  fi

  escaped_csv="$(escape_compose_value "$attachment_csv")"
  case "$remote_value" in
    xfeDoCommand\(composeMessage\))
      printf "xfeDoCommand(composeMessage,attachment='%s')" "$escaped_csv"
      ;;
    xfeDoCommand\(composeMessage,*\))
      printf "%s,attachment='%s')" "${remote_value%)}" "$escaped_csv"
      ;;
    *)
      printf '%s' "$remote_value"
      ;;
  esac
}

augment_compose_like_args_with_file_attachments() {
  local arg=""
  local normalized_arg=""
  local compose_like_mode=""
  local compose_like_index_in_rebuilt=-1
  local compose_like_value=""
  local skip_next=0
  local app_args_count=0
  local rebuilt_count=0
  local file_arg_count=0
  local staged_attachments=()
  local attachment_path=""

  local file_args=()
  local rebuilt_args=()

  app_args_count="$(printf '%s\n' "${APP_ARGS[@]}" | awk 'END { print NR + 0 }')"

  for ((i=0; i<app_args_count; i++)); do
    case "${APP_ARGS[$i]}" in
      -compose)
        if [ $((i + 1)) -lt "$app_args_count" ]; then
          compose_like_mode="compose"
          compose_like_value="${APP_ARGS[$((i + 1))]}"
        fi
        break
        ;;
      -remote)
        if [ $((i + 1)) -lt "$app_args_count" ] && [[ "${APP_ARGS[$((i + 1))]}" == xfeDoCommand\(composeMessage* ]]; then
          compose_like_mode="remote"
          compose_like_value="${APP_ARGS[$((i + 1))]}"
        fi
        break
        ;;
    esac
  done

  if [ -z "$compose_like_mode" ]; then
    return 0
  fi

  for ((i=0; i<app_args_count; i++)); do
    arg="${APP_ARGS[$i]}"
    if [ "$skip_next" = "1" ]; then
      skip_next=0
      if [ "$compose_like_index_in_rebuilt" -lt 0 ]; then
        compose_like_index_in_rebuilt="$rebuilt_count"
      fi
      rebuilt_args+=("$arg")
      rebuilt_count=$((rebuilt_count + 1))
      continue
    fi
    case "$arg" in
      -compose|-remote)
        rebuilt_args+=("$arg")
        rebuilt_count=$((rebuilt_count + 1))
        skip_next=1
        continue
        ;;
    esac
    normalized_arg="$(normalize_attachment_path "$arg")"
    if [ -n "$normalized_arg" ] && [ -f "$normalized_arg" ]; then
      file_args+=("$normalized_arg")
      file_arg_count=$((file_arg_count + 1))
      continue
    fi
    if [[ "$arg" == file://* ]]; then
      normalized_arg="$(normalize_attachment_path "$arg")"
      if [ -n "$normalized_arg" ] && [ -f "$normalized_arg" ]; then
        file_args+=("$arg")
        file_arg_count=$((file_arg_count + 1))
        continue
      fi
    fi
    rebuilt_args+=("$arg")
    rebuilt_count=$((rebuilt_count + 1))
  done

  if [ "$file_arg_count" -eq 0 ]; then
    return 0
  fi

  cleanup_staged_attachment_files
  for attachment_path in "${file_args[@]}"; do
    staged_attachments+=("$(stage_attachment_file "$attachment_path")")
  done

  compose_like_value="$(
    if [ "$compose_like_mode" = "compose" ]; then
      append_attachment_to_compose_value "$compose_like_value" "$(join_by_comma "${staged_attachments[@]}")"
    else
      append_attachment_to_remote_value "$compose_like_value" "$(join_by_comma "${staged_attachments[@]}")"
    fi
  )"

  if [ -n "$compose_like_value" ] && [ "$compose_like_index_in_rebuilt" -ge 0 ]; then
    rebuilt_args[$compose_like_index_in_rebuilt]="$compose_like_value"
  fi

  APP_ARGS=("${rebuilt_args[@]}")
}

get_runtime_stamp() {
  local runtime_inputs=()
  local item=""

  if [ -r "${APP_DIR}/omni.ja" ]; then
    runtime_inputs+=("${APP_DIR}/omni.ja")
  fi

  for item in "${APP_DIR}"/*.xpi; do
    if [ -r "$item" ]; then
      runtime_inputs+=("$item")
    fi
  done

  if [ -z "${runtime_inputs[*]}" ]; then
    return 1
  fi

  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "${runtime_inputs[@]}" 2>/dev/null | sha256sum 2>/dev/null | awk '{print $1}'
    return $?
  fi

  for item in "${runtime_inputs[@]}"; do
    stat -c '%n:%Y:%s' "$item" 2>/dev/null
  done | awk 'BEGIN { ORS="|" } { print }'
}

emit_profile_dir() {
  local path="$1"
  local is_relative="$2"
  local profile_dir=""

  if [ -z "$path" ]; then
    return 0
  fi

  if [ "$is_relative" = "1" ]; then
    profile_dir="${PROFILE_ROOT}/${path}"
  else
    profile_dir="$path"
  fi

  if [ -d "$profile_dir" ] && [ -f "${profile_dir}/prefs.js" ]; then
    printf '%s\n' "$profile_dir"
  fi
}

collect_profile_dirs() {
  local profiles_ini="${PROFILE_ROOT}/profiles.ini"
  local line=""
  local path=""
  local is_relative="1"

  if [ -f "$profiles_ini" ]; then
    while IFS= read -r line || [ -n "$line" ]; do
      case "$line" in
        "["*)
          emit_profile_dir "$path" "$is_relative"
          path=""
          is_relative="1"
          ;;
        Path=*)
          path="${line#Path=}"
          ;;
        IsRelative=*)
          is_relative="${line#IsRelative=}"
          ;;
      esac
    done < "$profiles_ini"
    emit_profile_dir "$path" "$is_relative"
  fi

  if [ -d "$PROFILE_ROOT" ]; then
    find "$PROFILE_ROOT" -mindepth 2 -maxdepth 2 -type d -name startupCache 2>/dev/null \
      | while IFS= read -r startup_cache_dir; do
          dirname "$startup_cache_dir"
        done
  fi
}

get_session_marker_pid() {
  local line=""

  if [ ! -f "$SESSION_MARKER" ]; then
    return 1
  fi

  while IFS= read -r line || [ -n "$line" ]; do
    case "$line" in
      pid=*)
        printf '%s\n' "${line#pid=}"
        return 0
        ;;
    esac
  done < "$SESSION_MARKER"

  return 1
}

session_marker_is_active() {
  local marker_pid=""

  marker_pid="$(get_session_marker_pid 2>/dev/null || true)"
  if [ -z "$marker_pid" ]; then
    return 1
  fi

  kill -0 "$marker_pid" 2>/dev/null
}

session_marker_is_stale() {
  if [ ! -f "$SESSION_MARKER" ]; then
    return 1
  fi

  if session_marker_is_active; then
    return 1
  fi

  return 0
}

profile_has_force_startup_cache_reset() {
  local profile_dir="$1"

  [ -f "${profile_dir}/${STARTUP_CACHE_FORCE_FLAG_NAME}" ]
}

write_profile_startup_login_suppress_flag() {
  local profile_dir="$1"

  if [ -z "$profile_dir" ] || [ ! -d "$profile_dir" ]; then
    return 0
  fi

  {
    printf 'at=%s\n' "$(date +%s)"
    printf 'reason=unclean-session-threshold\n'
  } > "${profile_dir}/${STARTUP_LOGIN_SUPPRESS_FLAG_NAME}" 2>/dev/null || true
}

read_unclean_exit_count() {
  if [ -f "$UNCLEAN_EXIT_COUNT_FILE" ]; then
    cat "$UNCLEAN_EXIT_COUNT_FILE" 2>/dev/null || true
  fi
}

write_unclean_exit_count() {
  local count="$1"

  mkdir -p "$PROFILE_ROOT" 2>/dev/null || true
  printf '%s\n' "$count" > "$UNCLEAN_EXIT_COUNT_FILE" 2>/dev/null || true
}

clear_unclean_exit_count() {
  rm -f -- "$UNCLEAN_EXIT_COUNT_FILE"
}

write_session_marker() {
  local app_pid="$1"

  mkdir -p "$PROFILE_ROOT" 2>/dev/null || true
  {
    printf 'pid=%s\n' "$app_pid"
    printf 'started=%s\n' "$(date +%s)"
  } > "$SESSION_MARKER" 2>/dev/null || true
}

clear_profile_startup_cache_if_needed() {
  local current_stamp=""
  local previous_stamp=""
  local profile_dir=""
  local startup_cache_dir=""
  local reason_xpi_changed=0
  local reason_stale_session=0
  local profile_force_reset=0
  local did_anything=0
  local unclean_exit_count=0

  if [ ! -d "$PROFILE_ROOT" ]; then
    return 0
  fi

  current_stamp="$(get_runtime_stamp 2>/dev/null || true)"

  if [ -f "$STARTUP_CACHE_STAMP" ]; then
    previous_stamp="$(cat "$STARTUP_CACHE_STAMP" 2>/dev/null || true)"
  fi

  if [ -n "$current_stamp" ] && [ "$current_stamp" != "$previous_stamp" ]; then
    reason_xpi_changed=1
  fi

  if session_marker_is_stale; then
    reason_stale_session=1
  fi

  unclean_exit_count="$(read_unclean_exit_count 2>/dev/null || true)"
  case "$unclean_exit_count" in
    ''|*[!0-9]*)
      unclean_exit_count=0
      ;;
  esac

  if [ "$reason_stale_session" = "1" ]; then
    unclean_exit_count=$((unclean_exit_count + 1))
    write_unclean_exit_count "$unclean_exit_count"
  fi

  while IFS= read -r profile_dir; do
    if [ -z "$profile_dir" ]; then
      continue
    fi

    profile_force_reset=0
    if profile_has_force_startup_cache_reset "$profile_dir"; then
      profile_force_reset=1
    fi

    if [ "$reason_xpi_changed" != "1" ] &&
       [ "$reason_stale_session" != "1" ] &&
       [ "$profile_force_reset" != "1" ]; then
      continue
    fi

    startup_cache_dir="${profile_dir}/startupCache"
    if [ -d "$startup_cache_dir" ]; then
      rm -rf -- "$startup_cache_dir"
      did_anything=1
    fi
    if [ "$profile_force_reset" = "1" ]; then
      rm -f -- "${profile_dir}/${STARTUP_CACHE_FORCE_FLAG_NAME}"
      did_anything=1
    fi
    if [ "$reason_stale_session" = "1" ] || [ "$profile_force_reset" = "1" ]; then
      write_profile_startup_login_suppress_flag "$profile_dir"
      did_anything=1
    fi
  done < <(collect_profile_dirs | sort -u)

  if [ "$reason_stale_session" = "1" ]; then
    rm -f -- "$SESSION_MARKER"
    did_anything=1
  fi

  if [ -n "$current_stamp" ] && [ "$did_anything" = "1" -o "$reason_xpi_changed" = "1" ]; then
    mkdir -p "$PROFILE_ROOT" 2>/dev/null || true
    printf '%s\n' "$current_stamp" > "$STARTUP_CACHE_STAMP" 2>/dev/null || true
  fi
}

# Core chrome/XHTML/JSM resources live in omni.ja, while extension parent
# scripts live in the bundled XPIs. startupCache must be invalidated when any
# of those runtime bundles changes, after an unclean previous shutdown, or
# after the runtime requested a self-healing cache reset for the profile.
clear_profile_startup_cache_if_needed

export LD_LIBRARY_PATH="${APP_DIR}"

APP_ARGS=("$@")
debug_log_args "argv.original" "$@"
if should_translate_xdg_email_args "$@"; then
  if translate_xdg_email_args "$@"; then
    APP_ARGS=("${TRANSLATED_APP_ARGS[@]}")
    debug_log_args "argv.translated_xdg" "${APP_ARGS[@]}"
  fi
fi

augment_compose_like_args_with_file_attachments

cleanup_staged_attachment_files
for i in "${!APP_ARGS[@]}"; do
  APP_ARGS[$i]="$(stage_attachment_references_in_string "${APP_ARGS[$i]}")"
done
debug_log_args "argv.final" "${APP_ARGS[@]}"

had_active_session=0
if session_marker_is_active; then
  had_active_session=1
fi

"${APP_BIN}" "${APP_ARGS[@]}" &
app_pid=$!
debug_log "app.spawned pid=${app_pid}"

if [ "$had_active_session" != "1" ]; then
  write_session_marker "$app_pid"
fi

wait "$app_pid"
app_status=$?

if [ "$had_active_session" != "1" ] && [ "$app_status" -eq 0 ]; then
  rm -f -- "$SESSION_MARKER"
  clear_unclean_exit_count
fi

exit "$app_status"