#!/bin/bash
# shellcheck shell=bash
# shellcheck disable=SC2086
# shellcheck disable=SC2144

Green="\033[32m"
Red="\033[31m"
Yellow='\033[33m'
Font="\033[0m"
INFO="[${Green}INFO${Font}]"
ERROR="[${Red}ERROR${Font}]"
WARN="[${Yellow}WARN${Font}]"
function INFO() {
    echo -e "${INFO} ${1}"
}
function ERROR() {
    echo -e "${ERROR} ${1}"
}
function WARN() {
    echo -e "${WARN} ${1}"
}

# 下载及解压
function download_and_unzip() {
    url="$1"
    target_dir="$2"
    INFO "正在下载 ${url}..."
    if curl ${CURL_OPTIONS} "${url}" ${CURL_HEADERS} | busybox unzip -d /tmp - > /dev/null; then
        if [ -e /tmp/MoviePilot-* ]; then
            mv /tmp/MoviePilot-* /tmp/"${target_dir}"
        fi
    else
        return 1
    fi
}

# 下载程序资源，$1: 后端版本路径
function install_backend_and_download_resources() {
    # 清理临时目录，上次安装失败可能有残留
    rm -rf /tmp/*
    if download_and_unzip "${GITHUB_PROXY}https://github.com/jxxghp/MoviePilot/archive/refs/${1}" "App"; then
        INFO "后端程序下载成功"
        INFO "依赖安装中..."
        pip install ${PIP_OPTIONS} --upgrade --root-user-action=ignore pip > /dev/null
        if pip install ${PIP_OPTIONS} --root-user-action=ignore -r /tmp/App/requirements.txt > /dev/null; then
            INFO "安装依赖成功"
            frontend_version=$(curl ${CURL_OPTIONS} "https://api.github.com/repos/jxxghp/MoviePilot-Frontend/releases/latest" ${CURL_HEADERS} | jq -r .tag_name)
            if [[ "${frontend_version}" == *v* ]]; then
                if download_and_unzip "${GITHUB_PROXY}https://github.com/jxxghp/MoviePilot-Frontend/releases/download/${frontend_version}/dist.zip" "dist"; then
                    INFO "前端程序下载成功"
                    # 提前备份插件目录
                    INFO "备份插件目录中..."
                    rm -rf /plugins
                    mkdir -p /plugins
                    cp -a /app/app/plugins/* /plugins/
                    # 不备份__init__.py
                    rm -f /plugins/__init__.py
                    # 提前备份旧 resources 资源
                    INFO "备份 resources 资源中..."
                    rm -rf /resources_bakcup
                    mkdir /resources_bakcup
                    cp -a /app/app/helper/* /resources_bakcup
                    # 清空目录
                    rm -rf /app
                    mkdir -p /app
                    # 后端程序
                    cp -a /tmp/App/* /app/
                    # 前端程序
                    rm -rf /public
                    mkdir -p /public
                    cp -a /tmp/dist/* /public/
                    # 清理临时目录
                    rm -rf /tmp/*
                    INFO "程序部分更新成功，前端版本：${frontend_version}，后端版本：${1}"
                    INFO "开始更新插件..."
                    if download_and_unzip "${GITHUB_PROXY}https://github.com/jxxghp/MoviePilot-Plugins/archive/refs/heads/main.zip" "Plugins"; then
                        INFO "插件下载成功"
                        # 恢复插件目录
                        cp -a /plugins/* /app/app/plugins/
                        # 插件仓库
                        rsync -av --remove-source-files /tmp/Plugins/plugins/* /app/app/plugins/ > /dev/null
                        # 提前安装插件依赖
                        find /app/app/plugins -name requirements.txt -exec pip install --root-user-action=ignore ${PIP_OPTIONS} -r {} \; > /dev/null
                        # 清理临时目录
                        rm -rf /tmp/*
                        INFO "插件更新成功"
                        INFO "开始更新资源包..."
                        if download_and_unzip "${GITHUB_PROXY}https://github.com/jxxghp/MoviePilot-Resources/archive/refs/heads/main.zip" "Resources"; then
                            INFO "资源包下载成功"
                            # 资源包
                            cp -a /tmp/Resources/resources/* /app/app/helper/
                            # 清理临时目录
                            rm -rf /tmp/*
                            INFO "资源包更新成功"
                        else
                            cp -a /resources_bakcup/* /app/app/helper/
                            rm -rf /resources_bakcup
                            WARN "资源包下载失败，继续使用旧的资源包来启动..."
                        fi
                    else
                        cp -a /plugins/* /app/app/plugins/
                        rm -rf /plugins
                        WARN "插件下载失败，继续使用旧的插件来启动..."
                    fi
                else
                    WARN "前端程序下载失败，继续使用旧的程序来启动..."
                fi
            else
                WARN "前端最新版本号获取失败，继续启动..."
            fi
        else
            ERROR "安装依赖失败，请重新拉取镜像"
        fi
    else
        WARN "后端程序下载失败，继续使用旧的程序来启动..."
    fi
}

function test_connectivity_pip() {
    pip uninstall -y pip-hello-world > /dev/null 2>&1
    case "$1" in
    0)
        if [[ -n "${PIP_PROXY}" ]]; then
            if pip install -i ${PIP_PROXY} pip-hello-world > /dev/null 2>&1; then
                PIP_OPTIONS="-i ${PIP_PROXY}"
                PIP_LOG="使用Pip镜像代理更新环境依赖"
                return 0
            fi
        fi
        return 1
        ;;
    1)
        if [[ -n "${PROXY_HOST}" ]]; then
            if pip install --proxy=${PROXY_HOST} pip-hello-world > /dev/null 2>&1; then
                PIP_OPTIONS="--proxy=${PROXY_HOST}"
                PIP_LOG="使用全局代理更新环境依赖"
                return 0
            fi
        fi
        return 1
        ;;
    2)
        PIP_OPTIONS=""
        PIP_LOG="不使用代理更新环境依赖"
        return 0
        ;;
    esac
}

function test_connectivity_github() {
    case "$1" in
    0)
        if [[ -n "${GITHUB_PROXY}" ]]; then
            if curl -sL "${GITHUB_PROXY}https://raw.githubusercontent.com/jxxghp/MoviePilot/main/README.md" > /dev/null 2>&1; then
                PIP_LOG="使用Github镜像代理更新程序"
                return 0
            fi
        fi
        return 1
        ;;
    1)
        if [[ -n "${PROXY_HOST}" ]]; then
            if curl -sL -x ${PROXY_HOST} https://raw.githubusercontent.com/jxxghp/MoviePilot/main/README.md > /dev/null 2>&1; then
                CURL_OPTIONS="-sL -x ${PROXY_HOST}"
                GITHUB_LOG="使用全局代理更新程序"
                return 0
            fi
        fi
        return 1
        ;;
    2)
        CURL_OPTIONS="-sL"
        GITHUB_LOG="不使用代理更新程序"
        return 0
        ;;
    esac
}

if [[ "${MOVIEPILOT_AUTO_UPDATE}" = "true" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}" = "release" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}" = "dev" ]]; then
    # 优先级：镜像站 > 全局 > 不代理
    # pip
    retries=0
    while true; do
        if test_connectivity_pip ${retries}; then
            break
        else
            retries=$((retries + 1))
        fi
    done
    # Github
    retries=0
    while true; do
        if test_connectivity_github ${retries}; then
            break
        else
            retries=$((retries + 1))
        fi
    done
    INFO "${PIP_LOG}，${GITHUB_LOG}"
    if [ -n "${GITHUB_TOKEN}" ]; then
        CURL_HEADERS="--oauth2-bearer ${GITHUB_TOKEN}"
    else
        CURL_HEADERS=""
    fi
    if [ "${MOVIEPILOT_AUTO_UPDATE}" = "dev" ]; then
        INFO "Dev 更新模式"
        install_backend_and_download_resources "heads/main.zip"
    else
        INFO "Release 更新模式"
        old_version=$(cat /app/version.py)
        if [[ "${old_version}" == *APP_VERSION* ]]; then
            current_version=v$(echo "${old_version}" | sed -ne "s/APP_VERSION\s=\s'v\(.*\)'/\1/gp")
            INFO "当前版本号：${current_version}"
            new_version=$(curl ${CURL_OPTIONS} "https://api.github.com/repos/jxxghp/MoviePilot/releases/latest" ${CURL_HEADERS} | jq -r .tag_name)
            if [[ "${new_version}" == *v* ]]; then
                release_version=${new_version}
                INFO "最新版本号：${release_version}"
                if [ "${current_version}" != "${release_version}" ]; then
                    INFO "发现新版本，开始自动升级..."
                    install_backend_and_download_resources "tags/${release_version}.zip"
                else
                    INFO "未发现新版本，跳过更新步骤..."
                fi
            else
                WARN "最新版本号获取失败，继续启动..."
            fi
        else
            WARN "当前版本号获取失败，继续启动..."
        fi
    fi
elif [[ "${MOVIEPILOT_AUTO_UPDATE}" = "false" ]]; then
    INFO "程序自动升级已关闭，如需自动升级请在创建容器时设置环境变量：MOVIEPILOT_AUTO_UPDATE=release"
else
    INFO "MOVIEPILOT_AUTO_UPDATE 变量设置错误"
fi
