#!/bin/bash

# =======================
# 颜色定义
# =======================
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# =======================
# 输入 .p7b 文件路径
# =======================
read -p "请输入 .p7b 文件路径: " P7B_PATH

# =======================
# 文件校验
# =======================
# 去除首尾空格
P7B_PATH=$(echo "$P7B_PATH" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')

if [ -z "$P7B_PATH" ]; then
    printf "%b\\n" "${RED}❌ 未输入文件路径${NC}"
    exit 1
fi

if [ ! -f "$P7B_PATH" ]; then
    printf "%b\\n" "${RED}❌ 文件不存在: $P7B_PATH${NC}"
    exit 1
fi

# 校验文件扩展名
EXT="${P7B_PATH##*.}"
if [[ "$EXT" != "p7b" && "$EXT" != "P7B" ]]; then
    printf "%b\\n" "${RED}❌ 文件类型不正确，请输入 .p7b 后缀的文件${NC}"
    exit 1
fi

# 校验文件大小
if [ ! -s "$P7B_PATH" ]; then
    printf "%b\\n" "${RED}❌ 文件为空${NC}"
    exit 1
fi

printf "%b\\n" "${GREEN}✅ 文件检查通过: $P7B_PATH${NC}"
echo ""

# =======================
# 读取文件内容，检测证书类型 + 提取 JSON 元数据（用 Python 处理二进制更可靠）
# =======================
if ! command -v python3 &>/dev/null; then
    printf "%b\\n" "${RED}❌ 需要 Python 3 来解析该格式的 .p7b 文件，请先安装${NC}"
    exit 1
fi

# Python 一次性提取：证书类型 + 所有 JSON 元数据，用 | 分隔
META=$(python3 - "$P7B_PATH" <<'PYEOF'
import sys, re
from datetime import datetime

with open(sys.argv[1], "rb") as f:
    text = f.read().decode("utf-8", errors="ignore")

def extract(pattern, default=""):
    m = re.search(pattern, text)
    return m.group(1) if m else default

# 证书类型
if "development-certificate" in text:
    cert_type = "development-certificate"
elif "distribution-certificate" in text:
    cert_type = "distribution-certificate"
else:
    cert_type = ""

# 元数据
bundle_name = extract(r'"bundle-name"\s*:\s*"([^"]*)"')
app_id = extract(r'"app-identifier"\s*:\s*"([^"]*)"')
dev_id = extract(r'"developer-id"\s*:\s*"([^"]*)"')
app_feature = extract(r'"app-feature"\s*:\s*"([^"]*)"')
version_name = extract(r'"version-name"\s*:\s*"([^"]*)"')
version_code = extract(r'"version-code"\s*:\s*(\d+)')
uuid_val = extract(r'"uuid"\s*:\s*"([^"]*)"')

# 有效期时间戳 → 可读日期
not_before = extract(r'"not-before"\s*:\s*(\d+)')
not_after = extract(r'"not-after"\s*:\s*(\d+)')
validity_from = datetime.fromtimestamp(int(not_before)).strftime("%Y-%m-%d %H:%M:%S") if not_before else ""
validity_to = datetime.fromtimestamp(int(not_after)).strftime("%Y-%m-%d %H:%M:%S") if not_after else ""

# 调试设备列表（如有）
devices_match = re.findall(r'"device-ids"\s*:\s*\[([^\]]*)\]', text)
debug_devices = ""
if devices_match:
    debug_devices = ",".join(re.findall(r'"([^"]*)"', devices_match[0]))

# 用 | 分隔输出一行
print("|".join([cert_type, bundle_name, app_id, dev_id, app_feature,
                version_name, version_code, uuid_val, validity_from, validity_to, debug_devices]))
PYEOF
)

# 解析 Python 输出（| 分隔）
CERT_TYPE=$(echo "$META" | cut -d'|' -f1)
BUNDLE_NAME=$(echo "$META" | cut -d'|' -f2)
APP_ID=$(echo "$META" | cut -d'|' -f3)
DEV_ID=$(echo "$META" | cut -d'|' -f4)
APP_FEATURE=$(echo "$META" | cut -d'|' -f5)
VERSION_NAME=$(echo "$META" | cut -d'|' -f6)
VERSION_CODE=$(echo "$META" | cut -d'|' -f7)
UUID_VAL=$(echo "$META" | cut -d'|' -f8)
VALIDITY_FROM=$(echo "$META" | cut -d'|' -f9)
VALIDITY_TO=$(echo "$META" | cut -d'|' -f10)
DEBUG_DEVICES=$(echo "$META" | cut -d'|' -f11)

# 显示证书类型
if [ "$CERT_TYPE" = "development-certificate" ]; then
    printf "%b\\n" "${BLUE}🔍 证书类型:${NC} ${YELLOW}调试证书 (development-certificate)${NC}"
elif [ "$CERT_TYPE" = "distribution-certificate" ]; then
    printf "%b\\n" "${BLUE}🔍 证书类型:${NC} ${GREEN}发布证书 (distribution-certificate)${NC}"
else
    printf "%b\\n" "${RED}❌ 未在文件中找到 development-certificate 或 distribution-certificate 字段${NC}"
    printf "%b\\n" "${YELLOW}请确认该文件是否为有效的鸿蒙签名 .p7b 文件${NC}"
    exit 1
fi

# 显示 JSON 元数据
echo ""
printf "%b\\n" "${CYAN}════════════════════════════════════════════${NC}"
printf "%b\\n" "${CYAN}             应用签名信息${NC}"
printf "%b\\n" "${CYAN}════════════════════════════════════════════${NC}"
echo ""
[ -n "$BUNDLE_NAME" ]   && printf "%b\\n" "📦 ${GREEN}Bundle Name:${NC}    $BUNDLE_NAME"
[ -n "$APP_ID" ]        && printf "%b\\n" "🆔 ${GREEN}App Identifier:${NC} $APP_ID"
[ -n "$DEV_ID" ]        && printf "%b\\n" "👤 ${GREEN}Developer ID:${NC}   $DEV_ID"
[ -n "$APP_FEATURE" ]   && printf "%b\\n" "📋 ${GREEN}App Feature:${NC}    $APP_FEATURE"
[ -n "$VERSION_NAME" ]  && printf "%b\\n" "📌 ${GREEN}Version:${NC}        $VERSION_NAME (code: $VERSION_CODE)"
[ -n "$UUID_VAL" ]      && printf "%b\\n" "🔗 ${GREEN}UUID:${NC}          $UUID_VAL"
[ -n "$VALIDITY_FROM" ] && printf "%b\\n" "📅 ${GREEN}有效期:${NC}        $VALIDITY_FROM → $VALIDITY_TO"

# 调试设备 UDID
if [ -n "$DEBUG_DEVICES" ]; then
    echo ""
    printf "%b\\n" "${BLUE}📱 授权调试设备 UDID:${NC}"
    echo "$DEBUG_DEVICES" | tr ',' '\n' | sed 's/^/   /'
fi
echo ""

# =======================
# 提取证书内容，生成 .cer 文件
# =======================
# 输出 cer 文件与 p7b 文件同目录，同名加 _tmp 后缀，不同扩展名
P7B_DIR=$(dirname "$P7B_PATH")
P7B_BASENAME=$(basename "$P7B_PATH" .p7b)
CER_FILE="${P7B_DIR}/${P7B_BASENAME}_tmp.cer"

# 使用 Python 做提取（bash 处理二进制 + JSON 混合内容太脆弱）
# Python 用 errors='ignore' 跳过不可解码字节，用正则提取证书块
if ! command -v python3 &>/dev/null; then
    printf "%b\\n" "${RED}❌ 需要 Python 3 来解析该格式的 .p7b 文件，请先安装${NC}"
    exit 1
fi

python3 - "$P7B_PATH" "$CERT_TYPE" "$CER_FILE" <<'PYEOF'
import sys, re

p7b_path = sys.argv[1]
cert_type = sys.argv[2]
cer_path = sys.argv[3]

# 读取文件，跳过不可解码字节
with open(p7b_path, "rb") as f:
    raw = f.read()
text = raw.decode("utf-8", errors="ignore")

# 从 cert_type 字段后提取 BEGIN...END 块（非贪婪）
pattern = rf'{re.escape(cert_type)}.*?(-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----)'
match = re.search(pattern, text, re.DOTALL)
if not match:
    print(f"❌ 未找到证书内容", file=sys.stderr)
    sys.exit(1)

cert_text = match.group(1)

# 去掉 BEGIN/END 标记，提取纯 base64
body = cert_text.replace("-----BEGIN CERTIFICATE-----", "")
body = body.replace("-----END CERTIFICATE-----", "")
# 去掉字面量 \n（两个字符 \ 和 n）
body = body.replace("\\n", "")
# 去掉所有空白（包括真实换行）
body = re.sub(r'\s+', '', body)

# 按 76 字符换行，组装标准 PEM
lines = [body[i:i+76] for i in range(0, len(body), 76)]
pem = "-----BEGIN CERTIFICATE-----\n" + "\n".join(lines) + "\n-----END CERTIFICATE-----\n"

with open(cer_path, "w") as f:
    f.write(pem)

print(f"✅ 证书文件已生成: {cer_path}")
PYEOF

if [ $? -ne 0 ]; then
    printf "%b\\n" "${RED}❌ 证书提取失败${NC}"
    exit 1
fi

# 校验 .cer 文件是否生成成功
if [ ! -s "$CER_FILE" ]; then
    printf "%b\\n" "${RED}❌ 无法从 .p7b 文件中提取证书内容${NC}"
    printf "%b\\n" "${YELLOW}请确认文件中包含有效的证书数据${NC}"
    exit 1
fi

echo ""

# =======================
# 查找 keytool
# =======================
find_keytool() {
    # 1. 先在 PATH 中查找
    if command -v keytool &>/dev/null; then
        command -v keytool
        return 0
    fi

    # 2. 检查 JAVA_HOME 环境变量
    if [ -n "$JAVA_HOME" ]; then
        if [ -f "$JAVA_HOME/bin/keytool" ]; then
            echo "$JAVA_HOME/bin/keytool"
            return 0
        fi
        if [ -f "$JAVA_HOME/bin/keytool.exe" ]; then
            echo "$JAVA_HOME/bin/keytool.exe"
            return 0
        fi
    fi

    # 3. Windows: 检查常见 JDK 路径
    if [ -d "/c/Program Files/Java" ] || [ -d "C:/Program Files/Java" ]; then
        for jdir in "/c/Program Files/Java"/* "C:/Program Files/Java"/*; do
            if [ -f "$jdir/bin/keytool.exe" ]; then
                echo "$jdir/bin/keytool.exe"
                return 0
            fi
        done
    fi

    return 1
}

KEYTOOL_CMD=$(find_keytool)

# =======================
# 使用 keytool 查询证书指纹
# =======================
printf "%b\\n" "${CYAN}════════════════════════════════════════════${NC}"
printf "%b\\n" "${CYAN}           证书详细信息${NC}"
printf "%b\\n" "${CYAN}════════════════════════════════════════════${NC}"
echo ""

if [ -n "$KEYTOOL_CMD" ]; then
    # 先验证 keytool 能否读取该 cer 文件
    if ! KEYTOOL_OUT=$("$KEYTOOL_CMD" -printcert -file "$CER_FILE" 2>&1); then
        printf "%b\\n" "${YELLOW}⚠️ keytool 无法直接读取，尝试重新整理证书格式...${NC}"
        # 提取 base64 内容，去掉所有空白，按 76 字符重新换行
        BASE64_ONLY=$(grep -v "BEGIN\|END" "$CER_FILE" | tr -d '[:space:]')
        if [ -n "$BASE64_ONLY" ]; then
            {
                echo "-----BEGIN CERTIFICATE-----"
                echo "$BASE64_ONLY" | fold -w 76
                echo "-----END CERTIFICATE-----"
            } > "$CER_FILE"
        fi
    fi

    # 输出完整证书信息
    printf "%b\\n" "${BLUE}📋 证书详情:${NC}"
    echo "────────────────────────────────────────"
    if KEYTOOL_OUT=$("$KEYTOOL_CMD" -printcert -file "$CER_FILE" 2>/dev/null); then
        echo "$KEYTOOL_OUT"
        echo "────────────────────────────────────────"
        echo ""

        # 提取 SHA256 指纹，去掉冒号和空格，转为 64 位小写十六进制
        FINGERPRINT=$(echo "$KEYTOOL_OUT" | \
            grep "SHA256:" | \
            sed 's/.*SHA256:[[:space:]]*//' | \
            tr -d ': ' | \
            tr 'A-F' 'a-f')

        if [ -n "$FINGERPRINT" ]; then
            printf "%b\\n" "${GREEN}✅ SHA256 指纹（64位，无冒号）:${NC}"
            printf "%b\\n" "${GREEN}$FINGERPRINT${NC}"
        else
            printf "%b\\n" "${YELLOW}⚠️ 未获取到 SHA256 指纹，尝试使用 SHA1...${NC}"
            FINGERPRINT=$("$KEYTOOL_CMD" -printcert -file "$CER_FILE" 2>/dev/null | \
                grep "SHA1:" | \
                sed 's/.*SHA1:[[:space:]]*//' | \
                tr -d ': ' | \
                tr 'A-F' 'a-f')
            if [ -n "$FINGERPRINT" ]; then
                printf "%b\\n" "${YELLOW}SHA1 指纹: $FINGERPRINT${NC}"
            fi
        fi
    else
        printf "%b\\n" "${RED}❌ keytool 无法读取证书文件，请手动检查: $CER_FILE${NC}"
    fi
elif command -v openssl &>/dev/null; then
    printf "%b\\n" "${YELLOW}⚠️ keytool 未安装，使用 openssl 替代查询${NC}"
    echo "────────────────────────────────────────"
    openssl x509 -in "$CER_FILE" -noout -text 2>/dev/null | head -30
    echo "────────────────────────────────────────"
    echo ""

    FINGERPRINT=$(openssl x509 -in "$CER_FILE" -noout -fingerprint -sha256 2>/dev/null | \
        sed 's/.*=//' | tr -d ': ' | tr 'A-F' 'a-f')
    if [ -n "$FINGERPRINT" ]; then
        printf "%b\\n" "${GREEN}✅ SHA256 指纹（64位，无冒号）:${NC}"
        printf "%b\\n" "${GREEN}$FINGERPRINT${NC}"
    fi
else
    printf "%b\\n" "${RED}❌ 未找到 keytool 或 openssl，请先安装 JDK 或 OpenSSL${NC}"
    exit 1
fi

echo ""
printf "%b\\n" "${CYAN}════════════════════════════════════════════${NC}"
printf "%b\\n" "📂 .cer 证书文件: ${GREEN}$CER_FILE${NC}"
printf "%b\\n" "${CYAN}════════════════════════════════════════════${NC}"
