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

standard_webstorm_app="/Applications/WebStorm.app"
standard_webstorm_bin="${standard_webstorm_app}/Contents/MacOS/webstorm"
toolbox_webstorm_cmd="${HOME}/Library/Application Support/JetBrains/Toolbox/scripts/webstorm"
timestamp="$(date +%Y%m%d-%H%M%S)"
open_target=""

usage() {
  cat <<'USAGE'
用法:
  bash fix-vue-devtools-webstorm-link.sh
  bash fix-vue-devtools-webstorm-link.sh --open <file[:line[:column]]>

作用:
  1. 找到当前正在运行的 WebStorm.app/Contents/MacOS/webstorm。
  2. 更新已有的 WebStorm.app 软链，或补齐缺失、无 Info.plist 的壳入口。
     完整的真实应用包保持原样，不替换包内二进制。
  3. 如果 JetBrains Toolbox 的 webstorm 命令是它生成的脚本，也备份后替换成同一个软链。

说明:
  这个脚本只修改本机软链和 Toolbox 生成的本地命令，不修改项目代码。
USAGE
}

while (($#)); do
  case "$1" in
    --open)
      if [[ $# -lt 2 ]]; then
        echo "缺少 --open 的文件参数。" >&2
        exit 2
      fi
      open_target="$2"
      shift 2
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "未知参数：$1" >&2
      usage >&2
      exit 2
      ;;
  esac
done

find_running_webstorm_bin() {
  local pid comm candidate=""

  while read -r pid comm; do
    case "$comm" in
      */WebStorm*.app/Contents/MacOS/webstorm)
        if [[ -x "$comm" ]]; then
          if [[ -n "$candidate" && "$candidate" != "$comm" ]]; then
            echo "检测到多个运行中的 WebStorm 入口，请只保留目标版本运行后重试。" >&2
            return 1
          fi
          candidate="$comm"
        fi
        ;;
    esac
  done < <(ps -axo pid=,comm=)

  if [[ -n "$candidate" ]]; then
    printf '%s\n' "$candidate"
  fi
}

find_latest_installed_webstorm_bin() {
  local app bin

  {
    find "${HOME}/Applications" /Applications -maxdepth 1 -type d -name 'WebStorm*.app' -print 2>/dev/null || true
  } | while IFS= read -r app; do
    bin="${app}/Contents/MacOS/webstorm"
    if [[ -x "$bin" ]]; then
      printf '%s\t%s\n' "$(stat -f '%m' "$app")" "$bin"
    fi
  done | sort -nr | awk -F '\t' 'NR == 1 { print $2 }'
}

ensure_symlink() {
  local link_path="$1"
  local target_path="$2"
  local backup_path

  mkdir -p "$(dirname "$link_path")"

  if [[ -L "$link_path" ]]; then
    local current_target
    current_target="$(readlink "$link_path")"
    if [[ "$current_target" == "$target_path" ]]; then
      echo "已是正确软链：$link_path -> $target_path"
      return 0
    fi

    if ! ln -sfn "$target_path" "$link_path"; then
      echo "更新软链失败：$link_path" >&2
      return 1
    fi
    echo "已更新软链：$link_path -> $target_path"
    return 0
  fi

  if [[ -e "$link_path" ]]; then
    backup_path="${link_path}.backup-${timestamp}"
    if ! mv "$link_path" "$backup_path"; then
      echo "备份原文件失败：$link_path" >&2
      return 1
    fi
    if ! ln -s "$target_path" "$link_path"; then
      echo "创建软链失败：$link_path" >&2
      return 1
    fi
    echo "原文件已备份：$backup_path"
    echo "已创建软链：$link_path -> $target_path"
    return 0
  fi

  if ! ln -s "$target_path" "$link_path"; then
    echo "创建软链失败：$link_path" >&2
    return 1
  fi
  echo "已创建软链：$link_path -> $target_path"
}

ensure_standard_webstorm_entry() {
  local target_bin="$1"
  local target_app="${target_bin%/Contents/MacOS/webstorm}"
  local backup_path

  if [[ "$standard_webstorm_bin" == "$target_bin" ]]; then
    echo "当前版本已经使用标准 WebStorm 入口：$standard_webstorm_bin"
    return 0
  fi

  if [[ -L "$standard_webstorm_app" ]]; then
    if ! ln -sfn "$target_app" "$standard_webstorm_app"; then
      echo "更新标准 WebStorm.app 软链失败：$standard_webstorm_app" >&2
      return 1
    fi
    echo "已更新标准 WebStorm.app 软链：$standard_webstorm_app -> $target_app"
    return 0
  fi

  if [[ -e "${standard_webstorm_app}/Contents/Info.plist" ]]; then
    echo "保留完整应用包：$standard_webstorm_app；请使用 Toolbox 的 webstorm 命令指定目标版本。"
    return 0
  fi

  if ensure_symlink "$standard_webstorm_bin" "$target_bin"; then
    return 0
  fi

  if [[ -d "$standard_webstorm_app" && ! -e "${standard_webstorm_app}/Contents/Info.plist" ]]; then
    backup_path="${standard_webstorm_app}.backup-${timestamp}"
    if ! mv "$standard_webstorm_app" "$backup_path"; then
      echo "备份旧 WebStorm.app 壳目录失败：$standard_webstorm_app" >&2
      return 1
    fi
    if ! ln -s "$target_app" "$standard_webstorm_app"; then
      echo "创建标准 WebStorm.app 软链失败：$standard_webstorm_app" >&2
      return 1
    fi
    echo "旧 WebStorm.app 壳目录已备份：$backup_path"
    echo "已创建标准 WebStorm.app 软链：$standard_webstorm_app -> $target_app"
    return 0
  fi

  echo "无法补齐标准 WebStorm 入口：$standard_webstorm_app，请检查目录类型和写权限。" >&2
  return 1
}

ensure_toolbox_command_link() {
  local target_path="$1"
  local backup_path

  mkdir -p "$(dirname "$toolbox_webstorm_cmd")"

  if [[ -L "$toolbox_webstorm_cmd" ]]; then
    ensure_symlink "$toolbox_webstorm_cmd" "$target_path"
    return 0
  fi

  if [[ -e "$toolbox_webstorm_cmd" ]]; then
    if grep -q 'Generated by JetBrains Toolbox' "$toolbox_webstorm_cmd"; then
      backup_path="${toolbox_webstorm_cmd}.backup-${timestamp}"
      mv "$toolbox_webstorm_cmd" "$backup_path"
      ln -s "$target_path" "$toolbox_webstorm_cmd"
      echo "Toolbox 生成的 webstorm 命令已备份：$backup_path"
      echo "已更新 Toolbox 命令软链：$toolbox_webstorm_cmd -> $target_path"
    else
      echo "跳过 Toolbox 命令：$toolbox_webstorm_cmd 不是 JetBrains Toolbox 生成的脚本。"
    fi
    return 0
  fi

  ln -s "$target_path" "$toolbox_webstorm_cmd"
  echo "已创建 Toolbox 命令软链：$toolbox_webstorm_cmd -> $target_path"
}

open_file_in_webstorm() {
  local target_bin="$1"
  local raw="$2"
  local file="$raw"
  local line="1"
  local column="1"

  if [[ "$raw" =~ ^(.+):([0-9]+):([0-9]+)$ ]]; then
    file="${BASH_REMATCH[1]}"
    line="${BASH_REMATCH[2]}"
    column="${BASH_REMATCH[3]}"
  elif [[ "$raw" =~ ^(.+):([0-9]+)$ ]]; then
    file="${BASH_REMATCH[1]}"
    line="${BASH_REMATCH[2]}"
  fi

  if [[ ! -f "$file" ]]; then
    echo "要打开的文件不存在：$file" >&2
    exit 1
  fi

  "$target_bin" --line "$line" --column "$column" "$file" >/dev/null 2>&1 &
  echo "已请求 WebStorm 打开：$file:$line:$column"
}

target_bin="$(find_running_webstorm_bin)"

if [[ -z "${target_bin:-}" ]]; then
  target_bin="$(find_latest_installed_webstorm_bin)"
fi

if [[ -z "${target_bin:-}" ]]; then
  echo "没有找到 WebStorm。请先启动 WebStorm，或确认它安装在 ~/Applications / /Applications 下。" >&2
  exit 1
fi

if [[ ! -x "$target_bin" ]]; then
  echo "找到的 WebStorm 入口不可执行：$target_bin" >&2
  exit 1
fi

echo "使用 WebStorm 入口：$target_bin"
"$target_bin" --version

ensure_standard_webstorm_entry "$target_bin"
ensure_toolbox_command_link "$target_bin"

echo
echo "复查标准入口："
ls -l "$standard_webstorm_bin"

if command -v webstorm >/dev/null 2>&1; then
  echo
  echo "复查 PATH 中的 webstorm：$(command -v webstorm)"
  webstorm --version || true
fi

if [[ -n "$open_target" ]]; then
  echo
  open_file_in_webstorm "$target_bin" "$open_target"
fi
