#!/bin/sh
# naixi 一键安装 — curl|sh 模式
# Usage:
#   curl -fsSL https://dl.naixi.net/ikuai/apps/install.sh | sh
set -eu

PRG="naixi"
DL_BASE="https://dl.naixi.net/ikuai/naixi"
ARCH_NAME=$(uname -m 2>/dev/null || echo unknown)
case "$ARCH_NAME" in
    x86_64|amd64) PKG_ARCH="amd64" ;;
    aarch64|arm64) PKG_ARCH="arm64" ;;
    *)
        if grep -q "^ARCH=arm" /etc/release 2>/dev/null; then
            PKG_ARCH="arm64"
        else
            PKG_ARCH="amd64"
        fi
        ;;
esac
PKG_URL="${DL_BASE}/naixi-0.6.6-${PKG_ARCH}.ipkg?t=$(date +%s)"
APPMARKET_DB="/etc/mnt/ikuai/appmarket.db"
DOCKER_DB="/etc/mnt/ikuai/docker.db"
IK_DIR="/usr/ikuai"

log() { echo "[$PRG] $*"; }
err() { echo "[$PRG] ERROR: $*" >&2; exit 1; }

# ─── 找安装盘：workdisk 可用时优先，否则回退 /etc/log ─────────────
WORKDISK=$(sqlite3 "$DOCKER_DB" "select workdisk from global" 2>/dev/null || echo "")
if [ -n "$WORKDISK" ] && [ -d "/etc/disk_user/$WORKDISK" ] && [ -w "/etc/disk_user/$WORKDISK" ]; then
    INSTALL_PATH="$WORKDISK"
    APPS_DIR="/etc/disk_user/$WORKDISK/apps"
    log "安装目标: $APPS_DIR (workdisk)"
else
    INSTALL_PATH="/etc/log"
    APPS_DIR="/etc/log/apps"
    log "未检测到可用 workdisk，安装目标: $APPS_DIR"
fi

# Existing Naixi installations stay on their registered storage. Older
# releases registered architecture-specific identities; treat all of them as
# the same logical app and migrate them to "naixi" below.
EXISTING_ROW=$(sqlite3 -separator '|' "$APPMARKET_DB" "select name,install_path,appid,enabled from applist where name in ('naixi','naixi-amd64','naixi-arm64') order by case name when 'naixi' then 0 else 1 end limit 1" 2>/dev/null || echo "")
EXISTING_NAME=$(printf '%s' "$EXISTING_ROW" | cut -d'|' -f1)
EXISTING_INSTALL_PATH=$(printf '%s' "$EXISTING_ROW" | cut -d'|' -f2)
EXISTING_APPID=$(printf '%s' "$EXISTING_ROW" | cut -d'|' -f3)
EXISTING_ENABLED=$(printf '%s' "$EXISTING_ROW" | cut -d'|' -f4)
case "$EXISTING_INSTALL_PATH" in
    /etc/log)
        if [ -d "/etc/log/apps/${EXISTING_NAME:-naixi}/.pkg" ]; then
            INSTALL_PATH="/etc/log"
            APPS_DIR="/etc/log/apps"
            log "检测到已有安装，保留目标: $APPS_DIR"
        fi
        ;;
    '') ;;
    *)
        if [ -d "/etc/disk_user/$EXISTING_INSTALL_PATH/apps/${EXISTING_NAME:-naixi}/.pkg" ]; then
            INSTALL_PATH="$EXISTING_INSTALL_PATH"
            APPS_DIR="/etc/disk_user/$EXISTING_INSTALL_PATH/apps"
            log "检测到已有安装，保留目标: $APPS_DIR"
        fi
        ;;
esac

APPMARKET_DIR="/var/appmarket"
MAX_APPID_FILE="/etc/mnt/ikuai/appmarket/.max_appid"

# ─── 下载 .ipkg ───────────────────────────────────────────────────
IPKG="/tmp/naixi-install-$$.ipkg"
trap 'rm -f "$IPKG"' EXIT

log "下载 naixi..."
if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$PKG_URL" -o "$IPKG" || err "下载失败"
elif command -v wget >/dev/null 2>&1; then
    wget -q -O "$IPKG" "$PKG_URL" || err "下载失败"
else
    err "需要 curl 或 wget"
fi
log "下载完成 ($(wc -c < "$IPKG") bytes)"

# ─── 解压 ─────────────────────────────────────────────────────────
TMP=$(mktemp -d 2>/dev/null || mktemp -d /tmp/naixi.XXXXXX)
trap 'rm -f "$IPKG"; rm -rf "$TMP"' EXIT

log "解压..."
tar xzf "$IPKG" -C "$TMP" 2>/dev/null || err "解压失败"

PKG_NAME=$(ls "$TMP")
[ -d "$TMP/$PKG_NAME" ] || err "包结构异常"
SRC="$TMP/$PKG_NAME"
MANIFEST="$SRC/manifest.json"
[ -f "$MANIFEST" ] || err "manifest.json 缺失"

# ─── 解析 manifest ────────────────────────────────────────────────
json_str() { awk -F'"' "/\"$1\"/{print \$4; exit}" "$MANIFEST"; }
PKG_ARCH_NAME=$(json_str name)
# Naixi is one logical app across architectures. Older packages used
# naixi-amd64/naixi-arm64 as archive roots; always register as "naixi".
case "$PKG_ARCH_NAME" in naixi|naixi-amd64|naixi-arm64) PKG_NAME="naixi" ;; *) PKG_NAME="$PKG_ARCH_NAME" ;; esac
VERSION=$(json_str version)
DISPLAY_NAME=$(json_str display_name)
[ -z "$DISPLAY_NAME" ] && DISPLAY_NAME=$(json_str name)
DESCRIPTION=$(json_str description)
TYPE=$(json_str type); [ -z "$TYPE" ] && TYPE=0
MAINTAINER=$(json_str maintainer)
MAINTAINER_URL=$(json_str maintainer_url)
DISTRIBUTOR=$(json_str distributor)
DISTRIBUTOR_URL=$(json_str distributor_url)

log "name=$PKG_NAME version=$VERSION type=$TYPE"

# ─── 分配 appid ───────────────────────────────────────────────────
cur=100000
[ -f "$MAX_APPID_FILE" ] && cur=$(cat "$MAX_APPID_FILE" 2>/dev/null || echo 100000)
dbmax=$(sqlite3 "$APPMARKET_DB" "select max(appid) from applist" 2>/dev/null || echo 0)
[ "$dbmax" -gt "$cur" ] 2>/dev/null && cur=$dbmax
if [ -n "$EXISTING_APPID" ]; then
    APPID="$EXISTING_APPID"
else
    APPID=$((cur + 1))
    echo "$APPID" > "$MAX_APPID_FILE" 2>/dev/null || true
fi

# ─── 安装 ─────────────────────────────────────────────────────────
APP_PATH="$APPS_DIR/$PKG_NAME"
log "安装到 $APP_PATH..."

# Stop the current logical instance, whether it uses the new or legacy name.
OLD_APP_PATH="$APP_PATH"
if [ -n "$EXISTING_NAME" ] && [ "$EXISTING_NAME" != "$PKG_NAME" ]; then
    OLD_APP_PATH="$APPS_DIR/$EXISTING_NAME"
fi
if [ -x "$OLD_APP_PATH/.pkg/scripts/stop.sh" ]; then
    cd "$OLD_APP_PATH/.pkg/scripts"
    ./stop.sh >> "$OLD_APP_PATH/log/run.log" 2>&1 2>/dev/null || true
    cd /
fi

# Migrate the architecture-specific directory without losing config, logs,
# backups, or appid.
if [ "$OLD_APP_PATH" != "$APP_PATH" ] && [ -d "$OLD_APP_PATH" ]; then
    if [ -e "$APP_PATH" ]; then
        err "新旧安装目录同时存在，请先备份并清理: $OLD_APP_PATH / $APP_PATH"
    fi
    mv "$OLD_APP_PATH" "$APP_PATH" || err "迁移旧安装目录失败"
    log "已迁移旧身份: $EXISTING_NAME -> $PKG_NAME"
fi

mkdir -p "$APP_PATH/.pkg" "$APP_PATH/log" "$APP_PATH/.tmp" "$APP_PATH/.backup"
cp -rf "$SRC/"* "$APP_PATH/.pkg/" 2>/dev/null || err "复制失败"

# Symlinks
if [ -d "$APP_PATH/.pkg/app/config" ]; then
    ln -sf .pkg/app/config "$APP_PATH/config"
    touch "$APP_PATH/config/environment"
    [ ! -e "$APP_PATH/.pkg/app/environment" ] && touch "$APP_PATH/.pkg/app/environment"
fi
[ -d "$APP_PATH/.pkg/app/data" ] && ln -sf .pkg/app/data "$APP_PATH/data"
[ -d "$APP_PATH/.pkg/app/cache" ] && ln -sf .pkg/app/cache "$APP_PATH/cache"

# Open-button metadata (iKuai WebUI reads app/environment for HOST_IP/APP_PORT_WEB/APP_WEB_LOGIN_URI)
LAN_IP=$(ip -4 addr show lan1 2>/dev/null | awk '/inet /{sub(/\/.*/,"",$2); print $2; exit}')
[ -n "$LAN_IP" ] || LAN_IP=$(ip -4 route get 223.5.5.5 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src") {print $(i+1); exit}}')
[ -n "$LAN_IP" ] || LAN_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
[ -n "$LAN_IP" ] || LAN_IP="192.168.1.1"
mkdir -p "$APP_PATH/.pkg/app"
{
    echo "HOST_IP=$LAN_IP"
    echo "APP_PORT_WEB=7681"
    echo "APP_WEB_LOGIN_URI=/"
} > "$APP_PATH/.pkg/app/environment"
# Keep .env defaults consistent without clobbering user-configured ttyd credentials.
grep -q '^HOST_IP=' "$APP_PATH/.pkg/app/.env" 2>/dev/null || echo "HOST_IP=$LAN_IP" >> "$APP_PATH/.pkg/app/.env"
grep -q '^APP_PORT_WEB=' "$APP_PATH/.pkg/app/.env" 2>/dev/null || echo "APP_PORT_WEB=7681" >> "$APP_PATH/.pkg/app/.env"
grep -q '^APP_WEB_LOGIN_URI=' "$APP_PATH/.pkg/app/.env" 2>/dev/null || echo "APP_WEB_LOGIN_URI=/" >> "$APP_PATH/.pkg/app/.env"


# Appmarket symlink
mkdir -p "$APPMARKET_DIR"
rm -f "$APPMARKET_DIR/naixi-amd64" "$APPMARKET_DIR/naixi-arm64"
ln -sfn "$APP_PATH" "$APPMARKET_DIR/$PKG_NAME"

# Icons
if [ -e "$APP_PATH/.pkg/ui/ico/app.png" ]; then
    mkdir -p "$IK_DIR/www/static/appmarket/$PKG_NAME/ico"
    cp -f "$APP_PATH/.pkg/ui/ico/app.png" "$IK_DIR/www/static/appmarket/$PKG_NAME/ico/"
fi
if [ -d "$APP_PATH/.pkg/ui/images" ]; then
    mkdir -p "$IK_DIR/www/static/appmarket/$PKG_NAME/images"
    cp -rf "$APP_PATH/.pkg/ui/images/"* "$IK_DIR/www/static/appmarket/$PKG_NAME/images/" 2>/dev/null || true
fi
rm -rf "$IK_DIR/www/static/appmarket/naixi-amd64" "$IK_DIR/www/static/appmarket/naixi-arm64"

# ─── 注册 appmarket.db (origin=0 开机自启 + 免费版保留) ────────────
TIMESTAMP=$(date +%s)
DESC_B64=$(printf '%s' "$DESCRIPTION" | base64 | tr -d '\n')
README=""
[ -e "$APP_PATH/.pkg/readme" ] && README=$(cat "$APP_PATH/.pkg/readme" | base64 | tr -d '\n')
CHANGELOG=""
[ -e "$APP_PATH/.pkg/changelog" ] && CHANGELOG=$(cat "$APP_PATH/.pkg/changelog" | base64 | tr -d '\n')

sqlite3 "$APPMARKET_DB" "DELETE FROM applist WHERE name in ('naixi','naixi-amd64','naixi-arm64')" 2>/dev/null || true
sqlite3 "$APPMARKET_DB" "INSERT INTO applist (
  enabled,name,appid,timestamp,display_name,location,ico,type,size,
  restart,current_version,maintainer,maintainer_url,distributor,distributor_url,
  origin,update_time,install_path,category,sub_category,desc,readme,changelog
) VALUES (
  '${EXISTING_ENABLED:-yes}','$PKG_NAME',$APPID,$TIMESTAMP,'$DISPLAY_NAME','','',$TYPE,0,
  0,'$VERSION','$MAINTAINER','$MAINTAINER_URL','$DISTRIBUTOR','$DISTRIBUTOR_URL',
  0,$TIMESTAMP,'$INSTALL_PATH',7,0,'$DESC_B64','$README','$CHANGELOG'
)" 2>/dev/null || err "写入 appmarket.db 失败"

log "已注册 (appid=$APPID, origin=0 开机自启)"

# ─── 启动 ─────────────────────────────────────────────────────────
SCRIPTS_DIR="$APP_PATH/.pkg/scripts"
if [ -d "$SCRIPTS_DIR" ]; then
    cd "$SCRIPTS_DIR"
    [ -x "./PRE_INST.sh" ] && ./PRE_INST.sh >/dev/null 2>&1 || true
    log "启动..."
    [ -x "./start.sh" ] && ./start.sh >> "$APP_PATH/log/run.log" 2>&1 || log "WARNING: start.sh 失败"
    [ -x "./POST_INST.sh" ] && ./POST_INST.sh >/dev/null 2>&1 || true
fi

echo "0" > "$APP_PATH/log/run.status"

# ─── 结果 ─────────────────────────────────────────────────────────
ENTERPRISE="0"
grep -q "NAIXI_ENTERPRISE_ENABLE=1" "$APP_PATH/.pkg/app/.env" 2>/dev/null && ENTERPRISE="1"

echo ""
echo "══════════════════════════════════════════"
echo " ✅ naixi v$VERSION 安装完成"
echo "══════════════════════════════════════════"
echo " 企业版:     $([ "$ENTERPRISE" = "1" ] && echo '✅ 已启用' || echo '❌ 未启用')"
echo " 网页终端:   http://\$(ip):7681  (admin/naixi)"
echo " 开机自启:   ✅ (origin=0)"
echo " anti-断网:  ✅ watchdog"
echo "══════════════════════════════════════════"
echo ""
echo "刷新 WebUI 查看企业版功能已解锁。"
exit 0
