#!/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 "依赖安装中..."
        ${PROXY_CHAINS} pip install ${PIP_OPTIONS} --upgrade --root-user-action pip > /dev/null
        if ${PROXY_CHAINS} pip install ${PIP_OPTIONS} --root-user-action -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 ${PROXY_CHAINS} pip install --root-user-action ${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
}

# 使用python进行URL解析，$1为PROXY_HOST
function parse_url() {
    local result
    result=$(./parse_url.py ${1})
    # 解析结果并提取各项
    PROTOCOL=$(echo "$result" | grep "^SCHEME:" | awk '{print $2}')
    USERNAME=$(echo "$result" | grep "^USERNAME:" | awk '{print $2}')
    PASSWORD=$(echo "$result" | grep "^PASSWORD:" | awk '{print $2}')
    HOST=$(echo "$result" | grep "^HOST:" | awk '{print $2}')
    PORT=$(echo "$result" | grep "^PORT:" | awk '{print $2}')
}

if [[ "${MOVIEPILOT_AUTO_UPDATE}" = "true" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}" = "release" ]] || [[ "${MOVIEPILOT_AUTO_UPDATE}" = "dev" ]]; then
    # 默认不使用proxychains代理PIP
    PROXY_CHAINS=""
    # 解析代理地址，判断代理合法性
    if [[ -n "${PROXY_HOST}" ]]; then
        parse_url "${PROXY_HOST}"
        INFO "检测到代理地址，开始解析..."
        if [[ "${PROTOCOL}" =~ ^http ]]; then
            PROXY_HOST_MODE="true"
            SOCKS_MODE="false"
        elif [[ "${PROTOCOL}" =~ ^socks ]]; then
            PROXY_HOST_MODE="true"
            SOCKS_MODE="true"
        else
            PROXY_HOST_MODE="false"
            SOCKS_MODE="false"
            WARN "【PROXY_HOST】代理地址错误，无法添加全局代理环境，开始使用其他更新方式"
        fi
    fi

    # 模式1：镜像站点代理
    if [[ -n "${PIP_PROXY}" ]] || [[ -n "${GITHUB_PROXY}" ]]; then
        # 通用代理参数
        GITHUB_PROXY=${GITHUB_PROXY:-""}
        # 模式1-1：全局代理补充本地网络代理，并修改pip支持socks代理
        if [[ "${PROXY_SUPPLEMENT}" = "true" ]] && [[ "${PROXY_HOST_MODE}" = "true" ]]; then
            CURL_OPTIONS="-sL -x ${PROXY_HOST}"
            # 针对socks模式下，启用proxychains
            if [[ "${SOCKS_MODE}" == "true" ]]; then
                PROXY_CHAINS="proxychains4 -f <( echo -e '[ProxyList]\n${PROTOCOL} ${HOST} ${PORT} ${USERNAME} ${PASSWORD}')"
                PIP_OPTIONS=${PIP_PROXY:+-i ${PIP_PROXY}}
            # http/https代理，不需要启用proxychains
            else
                PROXY_CHAINS=""
                # http/https代理下，优先使用-i镜像站
                if [[ -n "${PIP_PROXY}" ]]; then
                    PIP_OPTIONS="-i ${PIP_PROXY}"
                else
                    PIP_OPTIONS="--proxy=${PROXY_HOST}"
                fi
            fi
            # 双镜像站，去除proxychains
            if [[ -n "${PIP_OPTIONS}" && -n "${GITHUB_PROXY}" ]]; then
                PROXY_CHAINS=""
                INFO "使用Pip镜像代理更新环境依赖，使用Github镜像代理更新程序"
            # 单Github镜像站，保留proxychains
            elif [[ -z "${PIP_OPTIONS}" && -n "${GITHUB_PROXY}" ]];then
                # 全局为socks代理时，优先使用-i镜像站，去除proxychains
                if [[ -n "${PIP_OPTIONS}" ]]; then
                    PROXY_CHAINS=""
                fi
                INFO "使用全局代理更新环境依赖，使用Github镜像代理更新程序"
            # 单Pip镜像站，去除proxychains
            elif [[ -n "${PIP_OPTIONS}" &&  -z "${GITHUB_PROXY}" ]];then
                PROXY_CHAINS=""
                INFO "使用Pip镜像代理更新环境依赖，使用全局代理更新程序"
            # 没有镜像站，一般情况下不会出现，过不了第一层判断
            else
                INFO "使用全局代理更新程序与环境依赖"
            fi

        # 模式1-2：本地网络优先，不使用全局代理补全
        elif [[ "${PROXY_SUPPLEMENT}" = "false" ]]; then
            CURL_OPTIONS="-sL"
            PIP_OPTIONS=${PIP_PROXY:+-i ${PIP_PROXY}}
            PROXY_CHAINS=""
            # 双镜像站
            if [[ -n "${PIP_PROXY}" && -n "${GITHUB_PROXY}" ]]; then
                INFO "使用Pip镜像代理更新环境依赖，使用Github镜像代理更新程序"
            # 单Github镜像站
            elif [[ -z "${PIP_OPTIONS}" && -n "${GITHUB_PROXY}" ]]; then
                INFO "不使用代理更新环境依赖，使用Github镜像代理更新程序"
            # 单Pip镜像站
            elif [[ -n "${PIP_OPTIONS}" && -z "${GITHUB_PROXY}" ]]; then
                INFO "使用Pip镜像代理更新环境依赖，不使用代理更新程序"
            # 没有镜像站，一般情况下不会出现，过不了第一层判断
            else
                INFO "不使用任何代理更新程序与环境依赖"
            fi

        # 模式1-3：其他情况，一般不会出现
        else
            CURL_OPTIONS="-sL"
            PIP_OPTIONS=""
            GITHUB_PROXY=""
            PROXY_CHAINS=""
            WARN "出现了未知的情况，不使用任何代理更新程序与环境依赖"
        fi

    # 模式3：代理地址正常，则使用全局代理
    elif [[ -n "${PROXY_HOST}" && "${PROXY_HOST_MODE}" = "true" ]]; then
        CURL_OPTIONS="-sL -x ${PROXY_HOST}"
        # 针对socks模式下，启用proxychains4
        if [[ "${SOCKS_MODE}" == "true" ]]; then
            PIP_OPTIONS=""
            PROXY_CHAINS="proxychains4 -f <( echo -e '[ProxyList]\n${PROTOCOL} ${HOST} ${PORT} ${USERNAME} ${PASSWORD}')"
        else
            PROXY_CHAINS=""
            PIP_OPTIONS="--proxy=${PROXY_HOST}"
        fi
        GITHUB_PROXY=""
        PROXY_CHAINS=""
        INFO "使用全局代理更新程序与环境依赖"

    # 模式4：其他情况，统一不使用代理
    else
        CURL_OPTIONS="-sL"
        PIP_OPTIONS=""
        GITHUB_PROXY=""
        PROXY_CHAINS=""
        INFO "不使用任何代理更新程序与环境依赖"
    fi
    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
