#!/usr/bin/env bash
set -euo pipefail

shopt -s nullglob

dry_run=0
if [[ "${1:-}" == "--dry-run" ]]; then
  dry_run=1
fi

get_midlet_name_from_jar() {
  local jar_path="$1"
  local manifest_text
  manifest_text="$(unzip -p "$jar_path" META-INF/MANIFEST.MF 2>/dev/null || true)"
  [[ -n "$manifest_text" ]] || return 1

  local unfolded_manifest
  unfolded_manifest="$(printf '%s\n' "$manifest_text" | awk '
    BEGIN { line=""; }
    {
      if ($0 ~ /^ /) { sub(/^ /, "", $0); line=line $0; next; }
      if (line != "") print line;
      line=$0;
    }
    END { if (line != "") print line; }
  ')"

  local midlet_name
  midlet_name="$(printf '%s\n' "$unfolded_manifest" | awk -F': ' 'tolower($1)=="midlet-name"{print $2; exit}')"
  if [[ -z "${midlet_name:-}" ]]; then
    midlet_name="$(printf '%s\n' "$unfolded_manifest" | awk -F': ' 'tolower($1)=="midlet-1"{print $2; exit}')"
    if [[ -n "${midlet_name:-}" ]]; then
      midlet_name="${midlet_name%%,*}"
    fi
  fi

  midlet_name="$(printf '%s' "${midlet_name:-}" | sed 's/^[[:space:]]\+//; s/[[:space:]]\+$//')"
  [[ -n "$midlet_name" ]] || return 1

  printf '%s' "$midlet_name"
}

sanitize_filename_component() {
  local raw_name="$1"

  local sanitized
  sanitized="$(printf '%s' "$raw_name" | tr -d '\r\n\t')"
  sanitized="$(printf '%s' "$sanitized" | sed 's/[\/\\:*?"<>|]/_/g; s/[[:space:]]\+/ /g; s/^[[:space:]]\+//; s/[[:space:]]\+$//')"

  sanitized="$(printf '%s' "$sanitized" | sed 's/[[:space:]\.]\+$//')"

  if [[ -z "$sanitized" ]]; then
    return 1
  fi

  printf '%s' "$sanitized"
}

pick_nonconflicting_base_name() {
  local directory_path="$1"
  local desired_base_name="$2"

  local candidate_base_name="$desired_base_name"
  if [[ ! -e "$directory_path/$candidate_base_name.jar" && ! -e "$directory_path/$candidate_base_name.JAR" ]]; then
    printf '%s' "$candidate_base_name"
    return 0
  fi

  local counter=2
  while :; do
    candidate_base_name="$desired_base_name ($counter)"
    if [[ ! -e "$directory_path/$candidate_base_name.jar" && ! -e "$directory_path/$candidate_base_name.JAR" ]]; then
      printf '%s' "$candidate_base_name"
      return 0
    fi
    counter=$((counter + 1))
  done
}

rename_if_exists() {
  local source_path="$1"
  local target_path="$2"

  [[ -e "$source_path" ]] || return 0
  [[ "$source_path" == "$target_path" ]] && return 0

  if [[ $dry_run -eq 1 ]]; then
    echo "Would rename: $(basename -- "$source_path") -> $(basename -- "$target_path")"
  else
    mv -n -- "$source_path" "$target_path"
    echo "Renamed: $(basename -- "$source_path") -> $(basename -- "$target_path")"
  fi
}

renamed_anything=0

for jar_path in *.jar *.JAR; do
  [[ -f "$jar_path" ]] || continue

  jar_directory="$(dirname -- "$jar_path")"
  jar_filename="$(basename -- "$jar_path")"
  jar_extension=".${jar_filename##*.}"
  original_base_name="${jar_filename%$jar_extension}"

  midlet_name=""
  if ! midlet_name="$(get_midlet_name_from_jar "$jar_path")"; then
    echo "Skipping (no MIDlet name found): $jar_filename" >&2
    continue
  fi

  sanitized_name=""
  if ! sanitized_name="$(sanitize_filename_component "$midlet_name")"; then
    echo "Skipping (name sanitized to empty): $jar_filename" >&2
    continue
  fi

  target_base_name="$(pick_nonconflicting_base_name "$jar_directory" "$sanitized_name")"

  source_jar_path="$jar_directory/$original_base_name$jar_extension"
  source_jad_path="$jar_directory/$original_base_name.jad"
  source_jpg_path="$jar_directory/$original_base_name.jpg"

  target_jar_path="$jar_directory/$target_base_name.jar"
  target_jad_path="$jar_directory/$target_base_name.jad"
  target_jpg_path="$jar_directory/$target_base_name.jpg"

  rename_if_exists "$source_jar_path" "$target_jar_path"
  rename_if_exists "$source_jad_path" "$target_jad_path"
  rename_if_exists "$source_jpg_path" "$target_jpg_path"

  renamed_anything=1
done

if [[ $renamed_anything -eq 0 ]]; then
  echo "No files were renamed."
fi
