#!/bin/sh
# ProxyFlow 一键安装脚本（完整市场注册版）
# 安装后可在爱快应用市场界面管理（启停/开机自启/卸载）
# 用法：curl -fsSL https://dl.naixi.net/ikuai/install-proxyflow.sh | sh
# 指定密码：PROXYFLOW_PASSWORD=xxx curl -fsSL ... | sh
set -e

VERSION="3.3.19"
DL_BASE="https://dl.naixi.net/ikuai/apps"
APPMARKET_DB="/etc/mnt/ikuai/appmarket.db"
MAX_APPID_FILE="/etc/mnt/ikuai/appmarket/.max_appid"
IK_DIR="/usr/ikuai"
DEFAULT_APPS_DIR="/etc/disk_user/data/apps"

# ── 输出 ──────────────────────────────────────────────────
info()  { printf '\033[0;32m[✓] %s\033[0m\n' "$*"; }
warn()  { printf '\033[0;33m[!] %s\033[0m\n' "$*"; }
die()   { printf '\033[0;31m[✗] %s\033[0m\n' "$*" >&2; exit 1; }
step()  { printf '\033[0;36m[→] %s\033[0m\n' "$*"; }

# ── 检测架构 ──────────────────────────────────────────────
step "检测设备架构..."
case "$(uname -m 2>/dev/null)" in
  x86_64)  ARCH_TAG="amd64" ;;
  aarch64) ARCH_TAG="arm64" ;;
  *) die "不支持的架构：$(uname -m)（仅支持 x86_64 / aarch64）" ;;
esac
PKG_NAME="proxyflow-$ARCH_TAG"
APP_DIR="$DEFAULT_APPS_DIR/$PKG_NAME"
PKG_DIR="$APP_DIR/.pkg"
info "架构：$ARCH_TAG，应用名：$PKG_NAME"

# ── 检查已有版本 ──────────────────────────────────────────
UPGRADE=0
OLD_VER=""
if [ -f "$PKG_DIR/manifest.json" ]; then
  OLD_VER=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$PKG_DIR/manifest.json" 2>/dev/null \
            | grep -o '"[0-9][^"]*"' | tr -d '"' || true)
  if [ "$OLD_VER" = "$VERSION" ]; then
    warn "已安装 ProxyFlow $VERSION，跳过重复安装。"
    exit 0
  fi
  warn "检测到已安装版本 $OLD_VER，将升级到 $VERSION..."
  UPGRADE=1
fi

# ── 下载 ─────────────────────────────────────────────────
IPKG_FILE="/tmp/${PKG_NAME}-${VERSION}.ipkg"
step "下载 ProxyFlow $VERSION ($ARCH_TAG)..."
DL_URL="$DL_BASE/proxyflow-${VERSION}-${ARCH_TAG}.ipkg"
if command -v curl >/dev/null 2>&1; then
  curl -fsSL -o "$IPKG_FILE" "$DL_URL" || die "下载失败：$DL_URL"
elif command -v wget >/dev/null 2>&1; then
  wget -q -O "$IPKG_FILE" "$DL_BASE/proxyflow-${VERSION}-${ARCH_TAG}.ipkg" \
    || die "下载失败"
else
  die "找不到 curl 或 wget"
fi

# ── SHA256 校验 ───────────────────────────────────────────
step "校验文件完整性..."
case "$ARCH_TAG" in
  amd64) EXPECTED="ccef54fb9cc1c88533813b7e04ea2d18006e591d45a01a6d251fc11d3983d124" ;;
  arm64) EXPECTED="81ee81e2ef6e62b6a985e8d23a4d81748deccf86f9cb60535147719ae55921e5" ;;
esac
ACTUAL=$(sha256sum "$IPKG_FILE" 2>/dev/null | awk '{print $1}')
[ "$ACTUAL" = "$EXPECTED" ] || die "SHA256 校验失败（文件损坏或被篡改）"
info "SHA256 校验通过"

# ── 停旧版本 ──────────────────────────────────────────────
if [ "$UPGRADE" = "1" ] && [ -x "$PKG_DIR/scripts/stop.sh" ]; then
  step "停止旧版本..."
  cd "$PKG_DIR/scripts" && sh stop.sh >> "$APP_DIR/log/run.log" 2>&1 || true
  sleep 2
fi

# ── 解包（保留用户数据/配置/密码）─────────────────────────
step "解包安装..."
mkdir -p "$APP_DIR/.tmp" "$APP_DIR/.backup" "$APP_DIR/log"

# 升级时先把用户数据搬走
SAVEDIR="$APP_DIR/.tmp/save_$$"
if [ "$UPGRADE" = "1" ] && [ -d "$PKG_DIR" ]; then
  mkdir -p "$SAVEDIR"
  [ -d "$PKG_DIR/app/config" ] && mv "$PKG_DIR/app/config" "$SAVEDIR/config"
  [ -d "$PKG_DIR/app/cache"  ] && mv "$PKG_DIR/app/cache"  "$SAVEDIR/cache"
  [ -d "$PKG_DIR/app/data"   ] && mv "$PKG_DIR/app/data"   "$SAVEDIR/data"
  [ -f "$PKG_DIR/app/.env"   ] && mv "$PKG_DIR/app/.env"   "$SAVEDIR/.env"
  [ -f "$PKG_DIR/app/environment" ] && mv "$PKG_DIR/app/environment" "$SAVEDIR/environment"
  # 备份旧 .pkg
  mv "$PKG_DIR" "$APP_DIR/.backup/pkg_$(date +%Y%m%d%H%M%S)" 2>/dev/null || true
fi

# 解包新版本
TMP_EX="$APP_DIR/.tmp/ex_$$"
mkdir -p "$TMP_EX"
tar xzf "$IPKG_FILE" -C "$TMP_EX" || die "解包失败"
PKG_INNER=$(ls "$TMP_EX" | head -1)
[ -n "$PKG_INNER" ] || die "包内容为空"
# 关键：mv 前必须清空目标 .pkg，否则 mv 会把源目录塞成嵌套子目录
rm -rf "$PKG_DIR"
mkdir -p "$APP_DIR"
mv "$TMP_EX/$PKG_INNER" "$PKG_DIR"
rm -rf "$TMP_EX"

# 还原用户数据
if [ -d "$SAVEDIR" ]; then
  [ -d "$SAVEDIR/config" ] && { rm -rf "$PKG_DIR/app/config"; mv "$SAVEDIR/config" "$PKG_DIR/app/config"; }
  [ -d "$SAVEDIR/cache"  ] && { rm -rf "$PKG_DIR/app/cache";  mv "$SAVEDIR/cache"  "$PKG_DIR/app/cache"; }
  [ -d "$SAVEDIR/data"   ] && { rm -rf "$PKG_DIR/app/data";   mv "$SAVEDIR/data"   "$PKG_DIR/app/data"; }
  [ -f "$SAVEDIR/.env"   ] && mv "$SAVEDIR/.env"         "$PKG_DIR/app/.env"
  [ -f "$SAVEDIR/environment" ] && mv "$SAVEDIR/environment" "$PKG_DIR/app/environment"
  rm -rf "$SAVEDIR"
fi

# 确保目录存在
mkdir -p "$PKG_DIR/app/config" "$PKG_DIR/app/cache" "$PKG_DIR/app/data" "$APP_DIR/log"
[ -f "$PKG_DIR/app/environment" ] || touch "$PKG_DIR/app/environment"

# ── 写 .env（仅首次安装，升级时已还原旧 .env）─────────────
if [ "$UPGRADE" = "0" ] || [ ! -f "$PKG_DIR/app/.env" ]; then
  WEB_PORT="${PROXYFLOW_PORT:-28081}"
  WEB_PASS="${PROXYFLOW_PASSWORD:-ikuai8.com}"
  # 优先从爱快 config.db 的 lan_config 读 LAN IP（最权威，naixi 也用这个）
  LAN_IP=$(sqlite3 /etc/mnt/ikuai/config.db "select ip_mask from lan_config limit 1;" 2>/dev/null | cut -d/ -f1)
  # 兜底：从网卡枚举，排除 lo（scope host）和回环，只取 scope global
  if [ -z "$LAN_IP" ]; then
    LAN_IP=$(ip addr 2>/dev/null | awk '/inet .*scope global/{split($2,a,"/"); print a[1]; exit}')
  fi
  cat > "$PKG_DIR/app/.env" <<EOF
APP_PORT_WEB=$WEB_PORT
PROXYFLOW_TPROXY_ENABLE=1
PROXYFLOW_TPROXY_PORT=27893
PROXYFLOW_DNS_PORT=21053
PROXYFLOW_DNS_MODE=0
PROXYFLOW_BYPASS_CIDR=192.168.0.0/16,10.0.0.0/8,172.16.0.0/12
PROXYFLOW_WEB_USER=admin
PROXYFLOW_WEB_PASSWORD=$WEB_PASS
HOST_IP=${LAN_IP:-127.0.0.1}
EOF
else
  WEB_PORT=$(grep "^APP_PORT_WEB=" "$PKG_DIR/app/.env" 2>/dev/null | cut -d= -f2)
  WEB_PASS=$(grep "^PROXYFLOW_WEB_PASSWORD=" "$PKG_DIR/app/.env" 2>/dev/null | cut -d= -f2)
  LAN_IP=$(grep "^HOST_IP=" "$PKG_DIR/app/.env" 2>/dev/null | cut -d= -f2)
  [ -n "$WEB_PORT" ] || WEB_PORT=28081
  [ -n "$WEB_PASS" ] || WEB_PASS="（沿用原密码，未在 .env 中显式记录）"
fi

# ── 权限 ──────────────────────────────────────────────────
chmod 755 "$PKG_DIR/app/bin/proxyflowd" \
          "$PKG_DIR/scripts/start.sh" \
          "$PKG_DIR/scripts/stop.sh"

# ── 注册到应用市场 ────────────────────────────────────────
step "注册到应用市场..."

# 读取 manifest 里的 display_name/version
DISPLAY_NAME=$(grep -o '"display_name"[[:space:]]*:[[:space:]]*"[^"]*"' "$PKG_DIR/manifest.json" 2>/dev/null \
               | grep -o '"[^"]*"$' | tr -d '"' || echo "代理分流")
MAINTAINER=$(grep -o '"maintainer"[[:space:]]*:[[:space:]]*"[^"]*"' "$PKG_DIR/manifest.json" 2>/dev/null \
             | grep -o '"[^"]*"$' | tr -d '"' || echo "Nyarime")
MAINTAINER_URL=$(grep -o '"maintainer_url"[[:space:]]*:[[:space:]]*"[^"]*"' "$PKG_DIR/manifest.json" 2>/dev/null \
                 | grep -o '"[^"]*"$' | tr -d '"' || echo "https://naixi.net")

TIMESTAMP=$(date +%s)

# 分配 appid
APPID=$(sqlite3 "$APPMARKET_DB" "SELECT appid FROM applist WHERE name='$PKG_NAME';" 2>/dev/null || echo "")
if [ -z "$APPID" ] || [ "$APPID" = "0" ]; then
  # 新装：分配新 appid
  CUR_MAX=0
  [ -f "$MAX_APPID_FILE" ] && CUR_MAX=$(cat "$MAX_APPID_FILE" 2>/dev/null || echo 0)
  DB_MAX=$(sqlite3 "$APPMARKET_DB" "SELECT MAX(appid) FROM applist;" 2>/dev/null || echo 0)
  [ "$DB_MAX" -gt "$CUR_MAX" ] 2>/dev/null && CUR_MAX=$DB_MAX
  APPID=$((CUR_MAX + 1))
  echo "$APPID" > "$MAX_APPID_FILE" 2>/dev/null || true
fi

# 设置 install_path（这台设备上应用装在 data 分区）
INSTALL_PATH="data"

APP_ICO="/static/appmarket/$PKG_NAME/ico/app.png"

# INSERT or REPLACE
sqlite3 "$APPMARKET_DB" <<SQL 2>/dev/null || warn "appmarket.db 写入失败（市场可能不可见，但应用正常运行）"
INSERT OR REPLACE INTO applist (
  enabled, name, appid, timestamp, display_name, location, ico, type, size,
  restart, current_version, maintainer, maintainer_url, distributor, distributor_url,
  origin, update_time, ignore_update, install_path, category, sub_category,
  desc, desc_url, readme, changelog
) VALUES (
  'yes', '$PKG_NAME', $APPID, $TIMESTAMP, '$DISPLAY_NAME', '', '$APP_ICO', 0, 0,
  1, '$VERSION', '$MAINTAINER', '$MAINTAINER_URL', 'iKuai', 'https://github.com/ikuaidev',
  0, $TIMESTAMP, 0, '$INSTALL_PATH', 0, 0,
  '', '', '', ''
);
SQL

# ── 拷 icon ───────────────────────────────────────────────
ICON_DIR="$IK_DIR/www/static/appmarket/$PKG_NAME/ico"
mkdir -p "$ICON_DIR"
ICON_SRC="$PKG_DIR/ui/ico/app.png"
if [ -f "$ICON_SRC" ] && [ "$ICON_SRC" -ef "$ICON_DIR/app.png" ] 2>/dev/null; then
  :  # 已是同一文件，跳过
elif [ -f "$ICON_SRC" ]; then
  cp -f "$ICON_SRC" "$ICON_DIR/app.png" 2>/dev/null || true
fi
IMAGES_DIR="$IK_DIR/www/static/appmarket/$PKG_NAME/images"
mkdir -p "$IMAGES_DIR"
[ -d "$PKG_DIR/ui/images" ] && cp -rf "$PKG_DIR/ui/images/." "$IMAGES_DIR/" 2>/dev/null || true

# ── 启动 ──────────────────────────────────────────────────
step "启动 ProxyFlow..."
cd "$PKG_DIR/scripts"
sh start.sh >> "$APP_DIR/log/run.log" 2>&1 &
sleep 3

# ── 健康检查 ──────────────────────────────────────────────
PORT="${WEB_PORT:-28081}"
OK=0
for i in 1 2 3 4 5; do
  if curl -s -m 3 "http://127.0.0.1:$PORT/api/v1/firewall-sources" >/dev/null 2>&1; then
    OK=1; break
  fi
  sleep 2
done

rm -f "$IPKG_FILE"

echo ""
if [ "$OK" = "1" ]; then
  info "=================================================="
  info " ProxyFlow $VERSION 安装成功！"
  info "=================================================="
  info " 管理界面：http://${LAN_IP:-<设备LAN-IP>}:$PORT"
  info " 用户名：  admin"
  info " 密 码：  $WEB_PASS"
  info " 应用市场：设备 Web → 应用市场 → 已安装"
  info "=================================================="
else
  warn "服务未及时响应，请查看日志："
  warn "  tail -f $APP_DIR/log/run.log"
fi
