#!/bin/bash
# OpenMenu NX sample: Create 7z archives from the current selection.
#
# Modes:
#   1) If ALL selected items are ZIP archives:
#      Each ZIP is extracted and converted 1:1 into its own .7z archive.
#      Example: Archive.zip -> Archive.7z
#
#   2) Otherwise:
#      All selected files/folders are packed together into one .7z archive.
#
# Compression level is always maximum: -mx=9
#
# OpenMenu NX passes the selected paths as normal positional arguments: "$@".

set -u
set -o pipefail

lang="${OMNX_LANGUAGE:-${LANG:-en}}"
lang="${lang%%.*}"
lang="${lang%%_*}"
lang="${lang%%-*}"

case "$lang" in
  de)
    TXT_TITLE="OpenMenu NX – 7z"
    TXT_NO_SELECTION="Es sind keine Dateien oder Ordner ausgewählt."
    TXT_NO_7Z="7-Zip wurde auf diesem Mac nicht gefunden.

Installation mit Homebrew:

brew install sevenzip

Falls Homebrew noch nicht installiert ist, installiere es zuerst über brew.sh und führe anschließend den obigen Befehl im Terminal aus."
    TXT_INVALID="Mindestens ein ausgewählter Eintrag existiert nicht."
    TXT_EXTRACT_FAIL="Das ZIP-Archiv konnte nicht entpackt werden:"
    TXT_CREATE_FAIL="Das 7z-Archiv konnte nicht erstellt werden:"
    TXT_DONE_ONE="7z-Archiv erstellt:"
    TXT_DONE_MULTI="7z-Archive erstellt:"
    ;;
  es)
    TXT_TITLE="OpenMenu NX – 7z"
    TXT_NO_SELECTION="No hay archivos ni carpetas seleccionados."
    TXT_NO_7Z="No se encontró 7-Zip en este Mac.

Instalación con Homebrew:

brew install sevenzip

Si Homebrew aún no está instalado, instálalo primero desde brew.sh y luego ejecuta el comando anterior en Terminal."
    TXT_INVALID="Al menos uno de los elementos seleccionados no existe."
    TXT_EXTRACT_FAIL="No se pudo extraer el archivo ZIP:"
    TXT_CREATE_FAIL="No se pudo crear el archivo 7z:"
    TXT_DONE_ONE="Archivo 7z creado:"
    TXT_DONE_MULTI="Archivos 7z creados:"
    ;;
  fr)
    TXT_TITLE="OpenMenu NX – 7z"
    TXT_NO_SELECTION="Aucun fichier ou dossier n’est sélectionné."
    TXT_NO_7Z="7-Zip est introuvable sur ce Mac.

Installation avec Homebrew :

brew install sevenzip

Si Homebrew n’est pas encore installé, installez-le d’abord depuis brew.sh, puis exécutez la commande ci-dessus dans Terminal."
    TXT_INVALID="Au moins un élément sélectionné n’existe pas."
    TXT_EXTRACT_FAIL="Impossible d’extraire l’archive ZIP :"
    TXT_CREATE_FAIL="Impossible de créer l’archive 7z :"
    TXT_DONE_ONE="Archive 7z créée :"
    TXT_DONE_MULTI="Archives 7z créées :"
    ;;
  it)
    TXT_TITLE="OpenMenu NX – 7z"
    TXT_NO_SELECTION="Nessun file o cartella selezionato."
    TXT_NO_7Z="7-Zip non è stato trovato su questo Mac.

Installazione con Homebrew:

brew install sevenzip

Se Homebrew non è ancora installato, installalo prima da brew.sh e poi esegui il comando sopra nel Terminale."
    TXT_INVALID="Almeno uno degli elementi selezionati non esiste."
    TXT_EXTRACT_FAIL="Impossibile estrarre l’archivio ZIP:"
    TXT_CREATE_FAIL="Impossibile creare l’archivio 7z:"
    TXT_DONE_ONE="Archivio 7z creato:"
    TXT_DONE_MULTI="Archivi 7z creati:"
    ;;
  *)
    TXT_TITLE="OpenMenu NX – 7z"
    TXT_NO_SELECTION="No files or folders are selected."
    TXT_NO_7Z="7-Zip was not found on this Mac.

Install with Homebrew:

brew install sevenzip

If Homebrew is not installed yet, install it first from brew.sh and then run the command above in Terminal."
    TXT_INVALID="At least one selected item does not exist."
    TXT_EXTRACT_FAIL="The ZIP archive could not be extracted:"
    TXT_CREATE_FAIL="The 7z archive could not be created:"
    TXT_DONE_ONE="7z archive created:"
    TXT_DONE_MULTI="7z archives created:"
    ;;
esac

show_alert() {
  /usr/bin/osascript - "$TXT_TITLE" "$1" <<'APPLESCRIPT' >/dev/null 2>&1
on run argv
    display alert (item 1 of argv) message (item 2 of argv) as warning
end run
APPLESCRIPT
}

show_notification() {
  /usr/bin/osascript - "$TXT_TITLE" "$1" <<'APPLESCRIPT' >/dev/null 2>&1
on run argv
    display notification (item 2 of argv) with title (item 1 of argv)
end run
APPLESCRIPT
}

find_7z() {
  local candidate

  # Apple Silicon Homebrew, Intel Homebrew and MacPorts first.
  for candidate in \
    "/opt/homebrew/bin/7zz" \
    "/opt/homebrew/bin/7z" \
    "/usr/local/bin/7zz" \
    "/usr/local/bin/7z" \
    "/opt/local/bin/7zz" \
    "/opt/local/bin/7z"
  do
    if [ -x "$candidate" ]; then
      printf '%s\n' "$candidate"
      return 0
    fi
  done

  candidate="$(command -v 7zz 2>/dev/null || true)"
  if [ -n "$candidate" ] && [ -x "$candidate" ]; then
    printf '%s\n' "$candidate"
    return 0
  fi

  candidate="$(command -v 7z 2>/dev/null || true)"
  if [ -n "$candidate" ] && [ -x "$candidate" ]; then
    printf '%s\n' "$candidate"
    return 0
  fi

  return 1
}

unique_7z_path() {
  local directory="$1"
  local stem="$2"
  local candidate="$directory/$stem.7z"
  local n=1

  while [ -e "$candidate" ]; do
    candidate="$directory/${stem}_${n}.7z"
    n=$((n + 1))
  done

  printf '%s\n' "$candidate"
}

strip_extension() {
  local name="$1"
  case "$name" in
    *.*) printf '%s\n' "${name%.*}" ;;
    *)   printf '%s\n' "$name" ;;
  esac
}

if [ "$#" -eq 0 ]; then
  show_alert "$TXT_NO_SELECTION"
  exit 1
fi

SEVEN_ZIP="$(find_7z)" || {
  show_alert "$TXT_NO_7Z"
  exit 1
}

for source in "$@"; do
  if [ ! -e "$source" ]; then
    show_alert "$TXT_INVALID\n\n$source"
    exit 1
  fi
done

# Determine whether the selection consists exclusively of ZIP files.
all_zip=1
for source in "$@"; do
  if [ -d "$source" ]; then
    all_zip=0
    break
  fi

  ext="${source##*.}"
  ext="$(printf '%s' "$ext" | tr '[:upper:]' '[:lower:]')"
  if [ "$ext" != "zip" ]; then
    all_zip=0
    break
  fi
done

created_paths=()

if [ "$all_zip" -eq 1 ]; then
  # ZIP conversion mode:
  # Every selected ZIP becomes its own 7z archive containing the ZIP's contents,
  # not the ZIP file itself.
  for zip_file in "$@"; do
    output_dir="$HOME/Desktop"
    zip_name="$(/usr/bin/basename "$zip_file")"
    stem="$(strip_extension "$zip_name")"
    [ -n "$stem" ] || stem="Archive"

    out="$(unique_7z_path "$output_dir" "$stem")"

    tmp_root="$(/usr/bin/mktemp -d "${TMPDIR:-/tmp}/OpenMenuNX-7z.XXXXXX")" || exit 1
    extract_dir="$tmp_root/content"
    /bin/mkdir -p "$extract_dir"

    # ditto handles normal macOS ZIPs well and preserves macOS metadata better
    # than a plain unzip invocation.
    if ! /usr/bin/ditto -x -k "$zip_file" "$extract_dir"; then
      /bin/rm -rf "$tmp_root"
      show_alert "$TXT_EXTRACT_FAIL\n\n$zip_file"
      exit 1
    fi

    (
      cd "$extract_dir" || exit 1
      "$SEVEN_ZIP" a -t7z -mx=9 "$out" . >/dev/null
    )
    status=$?

    /bin/rm -rf "$tmp_root"

    if [ "$status" -ne 0 ] || [ ! -f "$out" ]; then
      show_alert "$TXT_CREATE_FAIL\n\n$out"
      exit 1
    fi

    created_paths+=("$out")
  done

else
  # Normal selection mode:
  # Create one archive on the user's Desktop. Finder selections normally share
  # the same parent folder. The first item supplies the archive name.
  first="$1"
  source_dir="$(/usr/bin/dirname "$first")"
  output_dir="$HOME/Desktop"
  first_name="$(/usr/bin/basename "$first")"

  if [ -d "$first" ]; then
    stem="$first_name"
  else
    stem="$(strip_extension "$first_name")"
  fi
  [ -n "$stem" ] || stem="OpenMenu NX Selection"

  out="$(unique_7z_path "$output_dir" "$stem")"

  # Run from the first item's parent so ordinary Finder selections are stored
  # with clean relative names rather than long absolute paths.
  all_same_parent=1
  for source in "$@"; do
    if [ "$(/usr/bin/dirname "$source")" != "$source_dir" ]; then
      all_same_parent=0
      break
    fi
  done

  if [ "$all_same_parent" -eq 1 ]; then
    args=()
    for source in "$@"; do
      args+=("$(/usr/bin/basename "$source")")
    done

    (
      cd "$source_dir" || exit 1
      "$SEVEN_ZIP" a -t7z -mx=9 "$out" "${args[@]}"
    ) >/dev/null
    status=$?
  else
    # Different source folders are unusual for a Finder selection. Preserve all
    # selected paths without moving/modifying the originals.
    "$SEVEN_ZIP" a -t7z -mx=9 "$out" "$@" >/dev/null
    status=$?
  fi

  if [ "$status" -ne 0 ] || [ ! -f "$out" ]; then
    show_alert "$TXT_CREATE_FAIL\n\n$out"
    exit 1
  fi

  created_paths+=("$out")
fi

# Reveal the first generated archive in Finder.
if [ "${#created_paths[@]}" -gt 0 ]; then
  /usr/bin/open -R "${created_paths[0]}"
fi

if [ "${#created_paths[@]}" -eq 1 ]; then
  show_notification "$TXT_DONE_ONE ${created_paths[0]}"
else
  show_notification "$TXT_DONE_MULTI ${#created_paths[@]}"
fi

exit 0