#!/usr/bin/env bash

set -u

export UUID="${UUID:-$(cat /proc/sys/kernel/random/uuid 2>/dev/null)}"
export APP_NAME="${APP_NAME:-$(tr -dc 'a-z' </dev/urandom | head -c 6)}"
export DEBIAN_FRONTEND=noninteractive
export ARGO_PORT="${ARGO_PORT:-8001}"
export ARGO_DOMAIN="${ARGO_DOMAIN:-}"
export ARGO_AUTH="${ARGO_AUTH:-}"
export NEZHA_SERVER="${NEZHA_SERVER:-}"
export NEZHA_PORT="${NEZHA_PORT:-}"
export NEZHA_KEY="${NEZHA_KEY:-}"
export SUB_PATH="${SUB_PATH:-}"

# 项目目录
if [ -d ".hermes" ]; then
    APP_DIR=".hermes/logs"
elif [ -d ".openclaw" ]; then
    APP_DIR=".openclaw/logs"
else
    APP_DIR="${PWD}/logs"
fi

# 创建目录并转换为绝对路径
mkdir -p "${APP_DIR}" || {
    echo "无法创建项目目录：${APP_DIR}"
    exit 1
}

APP_DIR="$(cd "${APP_DIR}" && pwd)" || {
    echo "无法进入项目目录"
    exit 1
}

STATE_FILE="${APP_DIR}/.project_type"

# 卸载模式
if [[ "${1:-}" == "-u" ||
      "${1:-}" == "u" ||
      "${1:-}" == "uninstall" ]]; then

    echo "执行卸载操作..."

    if [[ -f "${STATE_FILE}" ]]; then
        INSTALLED_TYPE="$(cat "${STATE_FILE}")"
        echo "检测到已安装项目：${INSTALLED_TYPE}"
    else
        echo "未检测到项目状态文件，将执行清理..."
    fi

    echo "清理 PM2 进程..."
    pm2 delete all 2>/dev/null || true
    pm2 save >/dev/null 2>&1 || true

    echo "删除 PM2 开机自启..."
    pm2 unstartup systemd -u root --hp /root >/dev/null 2>&1 || true

    echo "删除项目目录：${APP_DIR}"
    rm -rf "${APP_DIR}"

    echo
    echo -e "\e[1;32m卸载完成\033[0m"
    exit 0
fi

# 选择项目类型
if [[ "${1:-}" == "-js" ||
      "${1:-}" == "js" ||
      "${1:-}" == "nodejs" ]]; then

    PROJECT_TYPE="nodejs"

elif [[ "${1:-}" == "-py" ||
        "${1:-}" == "py" ||
        "${1:-}" == "python" ]]; then

    PROJECT_TYPE="python"

elif [[ -z "${1:-}" ]]; then

    RANDOM_CHOICE=$((RANDOM % 2))

    if [[ "${RANDOM_CHOICE}" -eq 0 ]]; then
        PROJECT_TYPE="nodejs"
        echo -e "\e[1;33m未指定项目类型，随机选择：Node.js\033[0m"
    else
        PROJECT_TYPE="python"
        echo -e "\e[1;33m未指定项目类型，随机选择：Python\033[0m"
    fi

else
    echo -e "\e[1;31m错误：无效参数\033[0m"
    echo
    echo "用法："
    echo "  bash install.sh          随机选择 Node.js 或 Python 项目"
    echo "  bash install.sh -js      安装 Node.js 项目"
    echo "  bash install.sh -py      安装 Python 项目"
    echo "  bash install.sh -u       卸载项目"
    exit 1
fi

# 保存项目类型
echo "${PROJECT_TYPE}" > "${STATE_FILE}"

cd "${APP_DIR}" || {
    echo "无法进入项目目录：${APP_DIR}"
    exit 1
}

echo "项目目录：${APP_DIR}"
echo "项目名称：${APP_NAME}"

# 生成环境变量文件
create_env_file() {
    echo "配置环境变量..."

    cat > "${APP_DIR}/.env" <<EOF
UUID=${UUID}
SHOW_LOG=no
EOF

    [[ -n "${SUB_PATH}" ]] &&
        echo "SUB_PATH=${SUB_PATH}" >> "${APP_DIR}/.env"

    [[ -n "${NEZHA_SERVER}" ]] &&
        echo "NEZHA_SERVER=${NEZHA_SERVER}" >> "${APP_DIR}/.env"

    [[ -n "${NEZHA_PORT}" ]] &&
        echo "NEZHA_PORT=${NEZHA_PORT}" >> "${APP_DIR}/.env"

    [[ -n "${NEZHA_KEY}" ]] &&
        echo "NEZHA_KEY=${NEZHA_KEY}" >> "${APP_DIR}/.env"

    [[ -n "${ARGO_DOMAIN}" ]] &&
        echo "ARGO_DOMAIN=${ARGO_DOMAIN}" >> "${APP_DIR}/.env"

    [[ -n "${ARGO_AUTH}" ]] &&
        echo "ARGO_AUTH=${ARGO_AUTH}" >> "${APP_DIR}/.env"

    [[ -n "${ARGO_PORT}" ]] &&
        echo "ARGO_PORT=${ARGO_PORT}" >> "${APP_DIR}/.env"

    chmod 600 "${APP_DIR}/.env"
}

# 安装 Node.js
install_nodejs() {
    if ! command -v node >/dev/null 2>&1; then
        echo "正在安装 Node.js，请稍等..."

        curl -fsSL https://deb.nodesource.com/setup_current.x | bash - >/dev/null 2>&1

        apt-get install -y -qq nodejs >/dev/null 2>&1 || {
            echo "Node.js 安装失败"
            exit 1
        }
    else
        echo "Node.js 已安装，跳过"
    fi
}

# 安装 PM2
install_pm2() {
    if ! command -v pm2 >/dev/null 2>&1; then
        echo "正在安装 PM2，请稍等..."

        npm install -g pm2 >/dev/null 2>&1 || {
            echo "PM2 安装失败"
            exit 1
        }
    else
        echo "PM2 已安装，跳过"
    fi
}

# Node.js 项目
if [[ "${PROJECT_TYPE}" == "nodejs" ]]; then

    install_nodejs
    install_pm2

    echo "下载 Node.js 项目文件..."

    wget -q -O "${APP_DIR}/index.html" \
        "https://raw.githubusercontent.com/eooce/node-ws/main/index.html" || {
        echo "index.html 下载失败"
        exit 1
    }

    wget -q -O "${APP_DIR}/index.js" \
        "https://raw.githubusercontent.com/eooce/nodejs-argo/native/index.js" || {
        echo "index.js 下载失败"
        exit 1
    }

    echo "初始化 npm..."
    npm init -y >/dev/null 2>&1

    echo "安装项目依赖，请稍等..."
    npm install axios ws dotenv koffi javascript-obfuscator >/dev/null 2>&1 || {
        echo "Node.js 依赖安装失败"
        exit 1
    }

    create_env_file

    echo "正在混淆 JavaScript 文件..."

    npx javascript-obfuscator "${APP_DIR}/index.js" \
        --output "${APP_DIR}/${APP_NAME}.js" \
        --compact true \
        --control-flow-flattening true \
        --control-flow-flattening-threshold 0.5 \
        --dead-code-injection true \
        --dead-code-injection-threshold 0.2 \
        --string-array true \
        --string-array-threshold 0.75 \
        --rename-globals false \
        >/dev/null 2>&1 || {
        echo "JavaScript 混淆失败"
        exit 1
    }

    rm -f "${APP_DIR}/index.js"

    echo "启动 Node.js 项目..."

    set -a
    source "${APP_DIR}/.env"
    set +a

    pm2 start "${APP_DIR}/${APP_NAME}.js" \
        --name "${APP_NAME}" \
        --cwd "${APP_DIR}" \
        >/dev/null 2>&1 || {
        echo "Node.js 项目启动失败"
        exit 1
    }

# Python 项目
elif [[ "${PROJECT_TYPE}" == "python" ]]; then

    if ! command -v python3 >/dev/null 2>&1; then
        echo "正在安装 Python3，请稍等..."

        apt-get update -y >/dev/null 2>&1
        apt-get install -y -qq python3 python3-venv python3-pip \
            >/dev/null 2>&1 || {
            echo "Python3 安装失败"
            exit 1
        }
    else
        echo "Python3 已安装，跳过"
    fi

    if ! command -v python3 >/dev/null 2>&1; then
        echo -e "\e[1;31mPython3 安装失败\033[0m"
        exit 1
    fi

    echo "安装 PM2..."

    if ! command -v pm2 >/dev/null 2>&1; then
        if ! command -v node >/dev/null 2>&1; then
            install_nodejs
        fi

        install_pm2
    else
        echo "PM2 已安装，跳过"
    fi

    echo "下载 Python 项目文件..."

    wget -q -O "${APP_DIR}/app.py" \
        "https://raw.githubusercontent.com/eooce/python-xray-argo/native/app.py" || {
        echo "app.py 下载失败"
        exit 1
    }

    wget -q -O "${APP_DIR}/index.html" \
        "https://github.com/eooce/python-ws/raw/refs/heads/main/index.html" || {
        echo "index.html 下载失败"
        exit 1
    }

    echo "创建 Python 虚拟环境..."

    python3 -m venv "${APP_DIR}/venv" || {
        echo "Python 虚拟环境创建失败"
        exit 1
    }

    source "${APP_DIR}/venv/bin/activate"

    echo "安装 Python 依赖..."

    pip install requests python-dotenv cryptography -qqq || {
        echo "Python 依赖安装失败"
        exit 1
    }

    create_env_file

    echo "正在混淆 Python 代码..."

    CODE_JSON="$(
        python3 -c '
import json
import sys

print(json.dumps(sys.stdin.read()))
' < "${APP_DIR}/app.py"
    )"

    OBFUSCATED="$(
        curl -fsS -X POST "https://obf.eooce.com/api/obfuscate" \
            -H "Content-Type: application/json" \
            -d "{\"code\": ${CODE_JSON}}" 2>/dev/null |
        python3 -c '
import json
import sys

try:
    data = json.load(sys.stdin)
    print(data.get("obfuscated", ""))
except Exception:
    print("")
'
    )"

    if [[ -n "${OBFUSCATED}" ]]; then
        printf '%s\n' "${OBFUSCATED}" > "${APP_DIR}/${APP_NAME}.py"
        rm -f "${APP_DIR}/app.py"
    else
        echo -e "\e[1;33m警告：代码混淆失败，将使用原始代码\033[0m"
        cp "${APP_DIR}/app.py" "${APP_DIR}/${APP_NAME}.py"
    fi

    echo "启动 Python 项目..."

    set -a
    source "${APP_DIR}/.env"
    set +a

    pm2 start "${APP_DIR}/${APP_NAME}.py" \
        --name "${APP_NAME}" \
        --cwd "${APP_DIR}" \
        --interpreter "${APP_DIR}/venv/bin/python3" \
        >/dev/null 2>&1 || {
        echo "Python 项目启动失败"
        exit 1
    }

fi

# 保存 PM2 开机自启
echo "配置 PM2 开机自启..."

pm2 startup systemd -u root --hp /root >/dev/null 2>&1 || true
pm2 save >/dev/null 2>&1 || true

echo "请稍等 35 秒，等待项目启动并生成节点..."
sleep 35

echo
echo -e "\e[1;32m安装完成\033[0m"
echo
echo "项目类型：${PROJECT_TYPE}"
echo "项目目录：${APP_DIR}"
echo "APP_NAME：${APP_NAME}"
echo "节点信息如下："

if [[ "${PROJECT_TYPE}" == "nodejs" ]]; then
    if [[ -f "${APP_DIR}/.npm/sub.txt" ]]; then
        cat "${APP_DIR}/.npm/sub.txt"
    else
        echo "未找到节点信息文件：${APP_DIR}/.npm/sub.txt"
        echo "请使用以下命令查看运行日志："
        echo "pm2 logs ${APP_NAME}"
    fi
elif [[ "${PROJECT_TYPE}" == "python" ]]; then
    if [[ -f "${APP_DIR}/.cache/sub.txt" ]]; then
        cat "${APP_DIR}/.cache/sub.txt"
    else
        echo "未找到节点信息文件：${APP_DIR}/.cache/sub.txt"
        echo "请使用以下命令查看运行日志："
        echo "pm2 logs ${APP_NAME}"
    fi
fi

echo
exit 0