#!/bin/bash
set -euo pipefail

# ============================================================
# Hermes Agent 安装脚本 — iOS 越狱版
# 适配：iPhone (iOS 15+, Procursus/NewTerm, apt 包管理)
# 作者：haij
# 注意：需要在 NewTerm 终端中以 root 用户运行
# ============================================================

PROJECT_DIR="$HOME/hermes-agent"
export UV_LINK_MODE=copy

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

# ---------- 1. 环境检测 ----------
echo -e "\n${GREEN}===== 检测系统环境 =====${NC}"

# 检测是否为 iOS 越狱环境
ARCH=$(uname -m)
if [[ "$ARCH" == "iPhone"* ]]; then
  echo -e "${GREEN}✅ 检测到：iOS 越狱环境${NC}"
  echo -e "  设备标识符：${CYAN}$ARCH${NC}"
  # iOS 上 uname -m 返回 iPhone14,5 这样的标识符
  # 实际 CPU 架构为 arm64e（iPhone 13 A15 芯片）
  REAL_ARCH="arm64"
elif [[ "$ARCH" == "arm64" ]]; then
  echo -e "${GREEN}✅ 检测到：ARM64 架构${NC}"
  REAL_ARCH="arm64"
else
  echo -e "${YELLOW}⚠ 未知架构：$ARCH，按 arm64 尝试…${NC}"
  REAL_ARCH="arm64"
fi

# 检查是否在 iOS 越狱环境
if [[ -d "/var/mobile" ]] || [[ -d "/var/jb" ]] || [[ -f "/var/root/Library/Caches/lockdownd.plist" ]]; then
  echo -e "${GREEN}✅ 确认：iOS 越狱设备${NC}"
  IS_IOS=true
else
  echo -e "${YELLOW}⚠ 非标准 iOS 环境，继续尝试…${NC}"
  IS_IOS=false
fi

# 检查是否为 root
if [[ "$(id -u)" != "0" ]]; then
  echo -e "${YELLOW}⚠ 建议以 root 用户运行（NewTerm 中执行 sudo -i 或 su）${NC}"
fi

# ---------- 2. 检测包管理器 ----------
echo -e "\n${GREEN}===== 检查包管理器 =====${NC}"
if command -v apt &>/dev/null; then
  echo -e "${GREEN}✅ apt 可用${NC}"
  PKG_MGR="apt"
  # 尝试修复可能的 dpkg 中断
  if [[ "$IS_IOS" == true ]]; then
    echo -e "${YELLOW}→ 检查 dpkg 状态…${NC}"
    apt-get check 2>/dev/null || true
  fi
else
  echo -e "${RED}❌ apt 不可用，iOS 越狱需安装 Procursus 或 Sileo${NC}"
  echo "请参考：https://github.com/ProcursusTeam/Procursus"
  exit 1
fi

# ---------- 3. 检测 Python ----------
echo -e "\n${GREEN}===== 检查 Python 版本 =====${NC}"
if command -v python3 &>/dev/null; then
  PY_VER=$(python3 --version 2>&1 | grep -oP '\d+\.\d+')
  echo "当前 Python：${CYAN}$PY_VER${NC}"
  if [[ "$IS_IOS" == true ]]; then
    # Procursus 最高只提供 Python 3.9，接受 3.9+
    if python3 -c "import sys; exit(0 if sys.version_info >= (3,9) else 1)" 2>/dev/null; then
      echo -e "${GREEN}✅ Python $PY_VER 满足要求（iOS 上接受 >= 3.9）${NC}"
    else
      echo -e "${RED}❌ Python 版本过低（$PY_VER），需要 3.9+${NC}"
      exit 1
    fi
  else
    # 非 iOS 环境要求 >= 3.11
    PY_VER=$(python3 --version 2>&1 | grep -oP '\d+\.\d+')
    echo "当前 Python：${CYAN}$PY_VER${NC}"
    if python3 -c "import sys; exit(0 if sys.version_info >= (3,11) else 1)" 2>/dev/null; then
      echo -e "${GREEN}✅ Python $PY_VER 满足要求（>= 3.11）${NC}"
    else
      echo -e "${YELLOW}⚠ Python $PY_VER 版本偏低，尝试升级…${NC}"
      NEED_PYTHON_UPGRADE=true
    fi
  fi
else
  echo -e "${YELLOW}⚠ 未检测到 Python3，将安装${NC}"
  NEED_PYTHON_UPGRADE=true
fi

# ---------- 4. 确认项目目录 ----------
echo -e "\n${GREEN}===== 确认项目目录 =====${NC}"
# 尝试多个可能的目录
for try_dir in "$PWD" "$PWD/.." "$HOME/hermes-agent" "$HOME/projects/hermes-agent"; do
  if [[ -f "$try_dir/pyproject.toml" ]]; then
    cd "$try_dir"
    echo -e "${GREEN}✅ 项目目录：$(pwd)${NC}"
    FOUND_PROJECT=true
    break
  fi
done

if [[ -z "${FOUND_PROJECT:-}" ]]; then
  echo -e "${YELLOW}⚠ 未找到 pyproject.toml${NC}"
  echo "请下载 iOS 适配版 Hermes Agent："
  echo "  cd ~"
  echo "  wget https://yule.chat/download/agent/hermes-agent-ios.tar.gz -O hermes-agent.tar.gz"
  echo "  tar -xzf hermes-agent.tar.gz && cd hermes-agent"
  echo -e "${YELLOW}然后重新运行本脚本${NC}"
  exit 1
fi

# ---------- 5. 安装编译工具和系统依赖 ----------
echo -e "\n${GREEN}===== 安装编译工具和依赖 =====${NC}"

if [[ "$IS_IOS" == true ]]; then
  # iOS 越狱环境不执行 apt update（源由越狱工具管理）
  # 只安装必要的包
  echo -e "${YELLOW}→ iOS 环境：跳过 apt update，直接安装依赖…${NC}"
  
  # 基础编译工具
  # Procursus 包名与 Debian 不完全一致，逐个安装
  for pkg in build-essential cmake ninja git wget curl; do
    if ! dpkg -s "$pkg" &>/dev/null 2>&1; then
      echo "安装：$pkg"
      apt-get install -y "$pkg" 2>&1 | tail -1 || echo -e "${YELLOW}⚠ $pkg 安装失败（可选依赖，跳过）${NC}"
    else
      echo -e "${GREEN}✅ $pkg 已安装${NC}"
    fi
  done
  # ninja-build 在 Procursus 中叫 ninja，两名字都试试
  if ! command -v ninja &>/dev/null && ! command -v ninja-build &>/dev/null; then
    echo -e "${YELLOW}⚠ ninja 未安装，不影响核心功能（仅影响部分 ML 依赖编译）${NC}"
  fi
else
  apt-get update -y 2>&1 | tail -3
  apt-get install -y build-essential cmake ninja-build git wget curl python3-dev
fi

# ---------- 6. 安装/升级 Python ----------
if [[ "${NEED_PYTHON_UPGRADE:-false}" == true ]]; then
  echo -e "\n${GREEN}===== 安装 Python 3.11+ =====${NC}"
  if [[ "$IS_IOS" == true ]]; then
    echo -e "${YELLOW}⚠ Procursus 源无更高版本 Python，继续使用 3.9${NC}"
  else
    apt-get install -y python3.11 python3.11-dev python3.11-venv 2>&1 | tail -3
  fi
fi

# 确保 pip 可用
if command -v pip3 &>/dev/null; then
  echo -e "${GREEN}✅ pip3 可用${NC}"
elif command -v pip &>/dev/null; then
  echo -e "${GREEN}✅ pip 可用${NC}"
else
  echo -e "${YELLOW}⚠ 未检测到 pip，尝试安装…${NC}"
  python3 -m ensurepip --upgrade 2>/dev/null || python3 -c "import urllib.request; exec(urllib.request.urlopen('https://bootstrap.pypa.io/get-pip.py').read())" 2>/dev/null || true
fi

# ---------- 7. 安装 Rust 工具链 ----------
echo -e "\n${GREEN}===== 安装 Rust 编译工具链 =====${NC}"
# pydantic v2 / cryptography 等包从源码编译时需要 Rust
# iOS 越狱 (Procursus) 无 rustc，rustup 也不识别 iPhone14,5
# 方案：跳过本机编译，全部用 PyPI 预编译 wheel
if command -v rustc &>/dev/null && command -v cargo &>/dev/null; then
  echo -e "${GREEN}✅ Rust 已安装：$(rustc --version)${NC}"
  HAS_RUST=true
else
  echo -e "${YELLOW}⚠ Rust 工具链未安装${NC}"
  if [[ "$IS_IOS" == true ]]; then
    echo -e "${YELLOW}→ iOS 越狱环境无 Rust 可用，跳过源码编译${NC}"
    echo -e "${YELLOW}→ 后续将使用 PyPI 预编译 wheel 安装依赖${NC}"
  fi
  HAS_RUST=false
fi

# 设置 pip 优先使用预编译 wheel（避免源码编译依赖 Rust）
export PIP_ONLY_BINARY="cryptography,pydantic,pydantic-core,pydantic-settings,pydantic-extra-types"

# ---------- 8. 项目依赖预处理 ----------
echo -e "\n${GREEN}===== 预装编译型 Python 依赖 =====${NC}"

# iOS 上 Rust 包强制 wheel，其余允许编译
if [[ "$IS_IOS" == true ]]; then
  echo -e "${YELLOW}→ 预装 pydantic / cryptography（wheel-only，避免 Rust 编译）…${NC}"
  pip3 install --only-binary cryptography,pydantic,pydantic-core cryptography pydantic 2>&1 | tail -3 || \
    echo -e "${YELLOW}⚠ 部分包 wheel 不可用（可能需 Rust，脚本会尝试继续）${NC}"
fi

# ---------- 9. 安装 pip 包管理器 ----------
echo -e "\n${GREEN}===== 安装/更新 pip =====${NC}"
if [[ "$IS_IOS" == true ]]; then
  echo -e "${YELLOW}→ iOS 环境：跳过 uv（不兼容），使用 pip${NC}"
  USE_PIP=true
  # 确保 pip 是最新版
  pip3 install --upgrade pip setuptools wheel 2>&1 | tail -2 || true
  # 如果是 Python 3.9，需要装 importlib_metadata 等 backport
  python3 -c "import sys; exit(0 if sys.version_info >= (3,11) else 1)" 2>/dev/null || \
    pip3 install importlib_metadata typing_extensions 2>&1 | tail -2 || true
else
  echo -e "${YELLOW}→ 安装 uv 包管理器…${NC}"
  if ! command -v uv &>/dev/null; then
    curl -LsSf https://astral.sh/uv/install.sh | sh
    if [[ -f "$HOME/.local/bin/uv" ]]; then
      export PATH="$HOME/.local/bin:$PATH"
    elif [[ -f "$HOME/.cargo/bin/uv" ]]; then
      export PATH="$HOME/.cargo/bin:$PATH"
    fi
  fi
  if command -v uv &>/dev/null; then
    uv --version
    USE_PIP=false
  else
    echo -e "${YELLOW}⚠ uv 安装失败，降级到 pip${NC}"
    USE_PIP=true
  fi
fi

# ---------- 10. 清理旧虚拟环境 ----------
echo -e "\n${GREEN}===== 清理旧环境 =====${NC}"
for dir in .venv venv __pycache__ build dist *.egg-info .pytest_cache .ruff_cache; do
  if [[ -e "$dir" ]]; then
    rm -rf "$dir"
    echo "已清除：$dir"
  fi
done
# ---------- 11. 安装依赖 ----------

echo -e "\n${GREEN}===== 安装 Hermes 依赖 =====${NC}"

# 在 iOS 上 python3-venv 包可能不存在，做降级准备
setup_venv() {
  python3 -m venv .venv 2>/dev/null && return 0
  echo -e "${YELLOW}→ python3 -m venv 不可用，尝试 virtualenv…${NC}"
  pip3 install virtualenv 2>/dev/null && virtualenv .venv 2>/dev/null && return 0
  echo -e "${YELLOW}→ virtualenv 也不行，直接安装在系统环境中${NC}"
  return 1
}

if [[ "$USE_PIP" == true ]]; then
  # pip 安装模式
  if setup_venv; then
    source .venv/bin/activate
  fi
  pip install --upgrade pip setuptools wheel 2>/dev/null || true

  # iOS + Python 3.9 兼容：先改 requires-python
  if [[ "$IS_IOS" == true ]]; then
    echo -e "${YELLOW}→ 适配 Python 3.9：修改 pyproject.toml 版本要求…${NC}"
    sed -i 's/requires-python = ">=3.11"/requires-python = ">=3.9"/' pyproject.toml
    echo -e "${GREEN}✅ requires-python 已改为 >=3.9${NC}"
  fi

  # 安装依赖（Python 3.9 兼容方案）
  if [[ "$IS_IOS" == true ]]; then
    echo -e "${YELLOW}→ iOS + Python 3.9：生成兼容依赖清单…${NC}"

    # 生成 Python 3.9 兼容的 requirements.txt
    # pydantic 2.12+ 放弃 Python 3.9 支持，锁定 <2.12
    cat > requirements-py39.txt << 'REQEOF'
openai>=2.21.0,<3
anthropic>=0.39.0,<1
python-dotenv>=1.2.1,<2
fire>=0.7.1,<1
httpx[socks]>=0.28.1,<1
rich>=14.3.3,<15
tenacity>=8.0.0,<9
ruamel.yaml>=0.17.0,<1
requests>=2.31.0,<2.33
jinja2>=3.1.5,<4
pydantic>=2.10.0,<2.12
prompt_toolkit>=3.0.52,<4
exa-py>=2.9.0,<3
croniter>=6.0.0,<7
edge-tts>=7.2.7,<8
PyJWT[crypto]>=2.12.0,<3
typing_extensions>=4.8.0
exceptiongroup>=1.2.0
REQEOF

    echo -e "${YELLOW}→ 安装依赖：Rust 包 wheel-only，其余允许源码编译…${NC}"
    pip install --only-binary pydantic,pydantic-core,cryptography -r requirements-py39.txt 2>&1 | tail -5

    # iOS: 如果 pydantic-core 没装成功（wheel 匹配失败），直接从 PyPI 下载 manylinux wheel
    echo -e "\n${YELLOW}→ 检查 pydantic-core 安装状态…${NC}"
    if ! python3 -c "import pydantic_core" 2>/dev/null; then
      echo -e "${YELLOW}→ pydantic-core 未安装，直接从 PyPI 下载 manylinux aarch64 wheel…${NC}"
      # 获取当前版本
      PC_VER=$(pip3 index versions pydantic-core 2>/dev/null | head -1 | grep -oP '\d+\.\d+\.\d+' | head -1)
      if [ -z "$PC_VER" ]; then
        # 固定一个已知兼容的版本
        PC_VER="2.27.2"
      fi
      echo -e "${YELLOW}→ 下载 pydantic-core==$PC_VER manylinux wheel…${NC}"
      WHEEL_URL=$(curl -sL "https://pypi.org/simple/pydantic-core/" 2>/dev/null | grep -oP "href=\"[^\"]*-cp39-cp39-manylinux[^"]*aarch64[^\"]*\.whl[^\"]*\"" | head -1 | grep -oP 'https?://[^"]+')
      if [ -n "$WHEEL_URL" ]; then
        echo -e "${GREEN}→ 找到 wheel: $(basename $WHEEL_URL)${NC}"
        curl -sL "$WHEEL_URL" -o /tmp/pydantic_core.whl
        pip install --no-deps /tmp/pydantic_core.whl 2>&1 | tail -3
        rm -f /tmp/pydantic_core.whl
      else
        echo -e "${YELLOW}⚠ 找不到 cp39 manylinux aarch64 wheel，尝试其他版本组合…${NC}"
        # 尝试其他常见 wheel 命名
        for ver in "$PC_VER" "2.27.1" "2.27.0" "2.26.0" "2.25.0"; do
          WHEEL_URL=$(curl -sL "https://pypi.org/simple/pydantic-core/" 2>/dev/null | grep -oP "href=\"[^\"]*-cp39-cp39-manylinux[^"]*aarch64[^\"]*\.whl[^\"]*\"" | grep -i "$ver" | head -1 | grep -oP 'https?://[^"]+')
          [ -n "$WHEEL_URL" ] && break
        done
        if [ -n "$WHEEL_URL" ]; then
          echo -e "${GREEN}→ 找到 wheel: $(basename $WHEEL_URL)${NC}"
          curl -sL "$WHEEL_URL" -o /tmp/pydantic_core.whl
          pip install --no-deps /tmp/pydantic_core.whl 2>&1 | tail -3
          rm -f /tmp/pydantic_core.whl
        else
          echo -e "${RED}❌ 找不到任何可用的 pydantic-core wheel${NC}"
          echo -e "${YELLOW}  可尝试：手动从 PyPI 下载后 pip install${NC}"
        fi
      fi
    else
      echo -e "${GREEN}✅ pydantic-core 已安装${NC}"
    fi

    # 同样处理 cryptography
    if ! python3 -c "import cryptography" 2>/dev/null; then
      echo -e "${YELLOW}→ cryptography 未安装，下载 manylinux aarch64 wheel…${NC}"
      CRYPT_VER=$(pip3 index versions cryptography 2>/dev/null | head -1 | grep -oP '\d+\.\d+\.\d+' | head -1 || echo "42.0.0")
      WHEEL_URL=$(curl -sL "https://pypi.org/simple/cryptography/" 2>/dev/null | grep -oP "href=\"[^\"]*-cp39-cp39-manylinux[^"]*aarch64[^\"]*\.whl[^\"]*\"" | head -1 | grep -oP 'https?://[^"]+')
      if [ -n "$WHEEL_URL" ]; then
        curl -sL "$WHEEL_URL" -o /tmp/cryptography.whl
        pip install --no-deps /tmp/cryptography.whl 2>&1 | tail -3
        rm -f /tmp/cryptography.whl
      fi
    fi

    # 不安装包本身，用 PYTHONPATH 指向源码目录
    echo -e "${YELLOW}→ 设置 PYTHONPATH 指向项目源码…${NC}"
    PROJECT_DIR=$(pwd)
    echo "export PYTHONPATH=\"$PROJECT_DIR:\$PYTHONPATH\"" >> "$HOME/.bashrc" 2>/dev/null || true
    echo "export PYTHONPATH=\"$PROJECT_DIR:\$PYTHONPATH\"" >> "$HOME/.zshrc" 2>/dev/null || true
    export PYTHONPATH="$PROJECT_DIR:$PYTHONPATH"

    # 验证关键依赖是否装上了
    echo -e "\n${YELLOW}→ 验证关键依赖…${NC}"
    for mod in openai anthropic pydantic httpx rich tenacity jinja2; do
      python3 -c "import $mod; v=getattr($mod, '__version__', 'ok'); print(f'  ✅ $mod=={v}')" 2>/dev/null || echo "  ❌ $mod"
    done
  else
    pip install . 2>&1 | tail -10
  fi
else
  # uv 安装模式（非 iOS）
  if uv venv 2>/dev/null; then
    source .venv/bin/activate
    uv pip install -e . 2>&1 | tail -10
  else
    echo -e "${YELLOW}→ uv venv 失败，降级到 pip${NC}"
    if setup_venv; then
      source .venv/bin/activate
    fi
    pip install . 2>&1 | tail -10
  fi
fi

# ---------- 12. 验证安装 ----------
echo -e "\n${GREEN}===== 安装验证 =====${NC}"
if [[ "$IS_IOS" == true ]]; then
  # iOS 上用 PYTHONPATH 方式，验证依赖
  echo -e "${YELLOW}→ 验证 Python 依赖环境…${NC}"
  MISSING=""
  for mod in openai anthropic pydantic httpx rich tenacity jinja2 pyyaml requests dotenv; do
    python3 -c "import $mod" 2>/dev/null || MISSING="$MISSING $mod"
  done
  if [[ -z "$MISSING" ]]; then
    echo -e "${GREEN}"
    echo "=============================================="
    echo "  Hermes Agent 依赖安装完成！（iOS 越狱版）"
    echo "  项目目录：$(pwd)"
    echo "  Python：$(python3 --version)"
    echo "  运行方式：cd $(pwd) && PYTHONPATH=. python hermes_cli"
    echo "  或先运行：export PYTHONPATH=\"$(pwd):\$PYTHONPATH\""
    echo "  然后：hermes --help"
    echo "=============================================="
    echo -e "${NC}"
  else
    echo -e "${RED}❌ 以下依赖缺失：$MISSING${NC}"
    echo -e "${YELLOW}请检查上面的安装日志${NC}"
  fi
elif python3 -c "from hermes_cli import main; print('Hermes Agent 验证通过')" 2>/dev/null; then
  echo -e "${GREEN}"
  echo "=============================================="
  echo "  Hermes Agent 安装完成！"
  echo "  项目目录：$(pwd)"
  echo "  使用命令：hermes --help"
  echo "=============================================="
  echo -e "${NC}"
else
  echo -e "${YELLOW}⚠ 验证未通过，尝试修复…${NC}"
  pip install --upgrade openai anthropic 2>&1 | tail -3 || true
  python3 -c "from hermes_cli import main; print('Hermes Agent 验证通过')" 2>/dev/null && echo -e "${GREEN}✅ 修复成功${NC}" || echo -e "${RED}❌ 仍有问题，请检查上面的错误信息${NC}"
fi

echo -e "\n${CYAN}──────────────────────────────────────────────${NC}"
echo -e "${CYAN}iOS 越狱注意事项：${NC}"
echo -e "  1. 如果终端关闭后找不到命令，运行："
echo -e "     export PATH=\"\$HOME/.local/bin:\$HOME/.cargo/bin:\$PATH\""
echo -e "  2. 建议将上面这行加到 ~/.bashrc 或 ~/.zshrc"
echo -e "  3. 如需开机自启，使用 launchd 或新立/其他进程工具"
echo -e "${CYAN}──────────────────────────────────────────────${NC}"
