#!/bin/bash
CERT_ERREXIT_WAS_SET=false
CERT_PIPEFAIL_WAS_SET=false
if [[ "$-" == *e* ]]; then
    CERT_ERREXIT_WAS_SET=true
fi
if shopt -qo pipefail; then
    CERT_PIPEFAIL_WAS_SET=true
fi
set -e
set -o pipefail

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}"
}

CERT_DIR="${CONFIG_DIR}/certs"
ACME_HOME="${CONFIG_DIR}/acme.sh"
ACME_DATA_DIR="${ACME_HOME}/data"
ACME_CERT_DIR="${CERT_DIR}/${SSL_DOMAIN}"
ACME_LATEST_CERT_DIR="${CERT_DIR}/latest"
NGINX_RELOAD_CMD="nginx -s reload 2>/dev/null || true"

# 恢复调用方原有 shell 选项，避免 source 本脚本后影响 entrypoint 后续流程。
function restore_shell_options() {
    if ! ${CERT_PIPEFAIL_WAS_SET}; then
        set +o pipefail
    fi
    if ! ${CERT_ERREXIT_WAS_SET}; then
        set +e
    fi
}

# 输出错误并恢复调用方 shell 选项，确保 source 失败时不会污染后续流程。
function exit_with_error() {
    ERROR "$1"
    restore_shell_options
    exit 1
}

# 使用固定的 acme.sh 工作目录执行命令，避免签发、安装和续期读取不同配置目录。
function run_acme() {
    LE_WORKING_DIR="${ACME_HOME}" \
        LE_CONFIG_HOME="${ACME_DATA_DIR}" \
        LE_CERT_HOME="${CERT_DIR}" \
        "${ACME_HOME}/acme.sh" --home "${ACME_HOME}" "$@"
}

# 维护 nginx 使用的稳定证书目录链接，兼容手动证书和自动签发证书路径。
function link_latest_cert_dir() {
    if [ -e "${ACME_LATEST_CERT_DIR}" ] && [ ! -L "${ACME_LATEST_CERT_DIR}" ]; then
        rm -rf "${ACME_LATEST_CERT_DIR}"
    fi
    ln -sfn "${ACME_CERT_DIR}" "${ACME_LATEST_CERT_DIR}"
}

# 配置证书自动续期；续期任务失败不应阻断已有证书启动。
function configure_cert_renewal() {
    if ! command -v cron >/dev/null 2>&1; then
        WARN "未安装 cron，跳过证书自动续期任务配置"
        return 0
    fi

    if ! mkdir -p /etc/cron.d 2>/dev/null; then
        WARN "无法创建 /etc/cron.d，跳过证书自动续期任务配置"
        return 0
    fi

    if ! printf "0 3 * * * root LE_WORKING_DIR=%q LE_CONFIG_HOME=%q LE_CERT_HOME=%q %q --cron --home %q\n" \
        "${ACME_HOME}" \
        "${ACME_DATA_DIR}" \
        "${CERT_DIR}" \
        "${ACME_HOME}/acme.sh" \
        "${ACME_HOME}" > /etc/cron.d/acme 2>/dev/null; then
        WARN "无法写入 /etc/cron.d/acme，跳过证书自动续期任务配置"
        return 0
    fi

    if ! chmod 644 /etc/cron.d/acme 2>/dev/null; then
        WARN "无法设置 /etc/cron.d/acme 权限，证书自动续期任务可能不会生效"
        return 0
    fi

    if ! pgrep -x cron >/dev/null 2>&1 && ! cron 2>/dev/null; then
        WARN "cron 启动失败，证书自动续期任务可能不会生效"
    fi
}

# 核心条件验证
if [ "${ENABLE_SSL}" = "true" ] && \
   [ "${AUTO_ISSUE_CERT}" = "true" ] && \
   [ -n "${SSL_DOMAIN}" ]; then

    # 创建证书目录
    mkdir -p "${ACME_CERT_DIR}"
    if id moviepilot >/dev/null 2>&1; then
        chown moviepilot:moviepilot "${CERT_DIR}" -R
    fi

    # 安装acme.sh（使用官方安装脚本）
    if [ ! -f "${ACME_HOME}/acme.sh" ]; then
        INFO "→ 安装acme.sh..."

        # 执行官方安装命令（添加错误处理）
        INFO "正在下载并安装 acme.sh..."
        
        install_args=("--install-online")
        if [ -n "${SSL_EMAIL}" ]; then
            install_args+=("--accountemail" "${SSL_EMAIL}")
        else
            WARN "未设置SSL_EMAIL，建议配置邮箱用于证书过期提醒"
        fi
        
        if ! curl -sSL https://get.acme.sh | \
            LE_WORKING_DIR="${ACME_HOME}" \
            LE_CONFIG_HOME="${ACME_DATA_DIR}" \
            LE_CERT_HOME="${CERT_DIR}" \
            sh -s -- "${install_args[@]}"; then
            exit_with_error "acme.sh 安装失败"
        fi

        # 验证安装是否成功
        if [ ! -f "${ACME_HOME}/acme.sh" ]; then
            exit_with_error "acme.sh 安装后文件不存在，安装可能失败"
        fi

        INFO "acme.sh 安装成功"
    fi

    # 签发证书（仅当证书不存在时）
    if [ ! -f "${ACME_CERT_DIR}/fullchain.pem" ] || [ ! -f "${ACME_CERT_DIR}/privkey.pem" ]; then
        # 必要参数检查
        REQUIRED_VARS=("DNS_PROVIDER")
        for var in "${REQUIRED_VARS[@]}"; do
            eval "value=\${${var}}"
            [ -z "$value" ] && exit_with_error "必须设置环境变量: ${var}"
        done

        INFO "→ 签发证书: ${SSL_DOMAIN} (DNS验证方式: ${DNS_PROVIDER})"

        # 加载ACME环境变量（带安全过滤）
        acme_exported_vars=()
        acme_original_keys=()
        acme_original_values=()
        acme_had_original_values=()
        while IFS= read -r var_name; do
            [ -z "${var_name}" ] && continue
            key="${var_name#ACME_ENV_}"
            value="${!var_name}"

            # 过滤非法变量名
            if [[ "$key" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]]; then
                acme_original_keys+=("${key}")
                if eval "[ -n \"\${${key}+x}\" ]"; then
                    acme_had_original_values+=("true")
                    acme_original_values+=("$(eval "printf '%s' \"\${${key}}\"")")
                else
                    acme_had_original_values+=("false")
                    acme_original_values+=("")
                fi
                export "$key"="$value"
                acme_exported_vars+=("${key}")
            else
                WARN "跳过无效变量名: ${key}"
            fi
        done < <(compgen -A variable ACME_ENV_ || true)

        # 签发证书（添加错误处理）
        INFO "正在签发证书..."
        if ! run_acme --issue \
            --dns "${DNS_PROVIDER}" \
            --domain "${SSL_DOMAIN}" \
            --force; then
            exit_with_error "证书签发失败"
        fi

        INFO "正在安装证书文件..."
        if ! run_acme --install-cert \
            --domain "${SSL_DOMAIN}" \
            --key-file "${ACME_CERT_DIR}/privkey.pem" \
            --fullchain-file "${ACME_CERT_DIR}/fullchain.pem" \
            --reloadcmd "${NGINX_RELOAD_CMD}"; then
            exit_with_error "证书安装失败"
        fi

        for index in "${!acme_original_keys[@]}"; do
            var_name="${acme_original_keys[$index]}"
            if [ "${acme_had_original_values[$index]}" = "true" ]; then
                export "${var_name}=${acme_original_values[$index]}"
            else
                unset "${var_name}"
            fi
        done

        # 创建稳定符号链接
        link_latest_cert_dir
        INFO "证书签发成功"
    else
        link_latest_cert_dir
        INFO "证书已存在，跳过签发步骤"
    fi

    # 配置自动更新任务
    INFO "→ 配置cron自动更新..."
    configure_cert_renewal

elif [ "${ENABLE_SSL}" = "true" ] && [ "${AUTO_ISSUE_CERT}" = "true" ] && [ -z "${SSL_DOMAIN}" ]; then
    exit_with_error "已启用自动签发证书但未设置 SSL_DOMAIN，无法生成 HTTPS 证书"
elif [ "${ENABLE_SSL}" = "true" ] && [ "${AUTO_ISSUE_CERT}" = "false" ]; then
    INFO "SSL已启用但自动签发证书已禁用，将使用手动配置的证书"
    # 检查证书文件是否存在
    if [ -f "${ACME_LATEST_CERT_DIR}/fullchain.pem" ] && [ -f "${ACME_LATEST_CERT_DIR}/privkey.pem" ]; then
        INFO "检测到证书文件，SSL配置正常"
    else
        exit_with_error "未检测到证书文件，请将 fullchain.pem 和 privkey.pem 放入 ${ACME_LATEST_CERT_DIR}"
    fi
fi

restore_shell_options
