#!/usr/bin/env bash
set -euo pipefail

# 修复 Xcode Organizer 显示 “Generic Xcode Archive” 的问题：
# - 某些情况下 xcodebuild 生成的 .xcarchive/Info.plist 缺少 ApplicationProperties
# - Organizer 无法识别归档中的主 App（即使 Products/Applications/*.app 存在）
#
# 说明：
# - 该脚本的核心作用是让 Organizer 能识别归档里的主 App，从而出现“分发/上传 TestFlight”入口。
# - 这类问题通常发生在命令行/CI 归档（xcodebuild archive）或某些自定义归档流程中，
#   导致 .xcarchive/Info.plist 缺少/不完整。
#
# 用法：
#   ./scripts/fix-xcarchive-header.sh "/path/to/xxx.xcarchive"

ARCHIVE_PATH="${1:-}"
if [[ -z "$ARCHIVE_PATH" ]]; then
  echo "用法: $0 \"/path/to/xxx.xcarchive\"" >&2
  exit 2
fi

if [[ ! -d "$ARCHIVE_PATH" ]]; then
  echo "错误：找不到归档目录：$ARCHIVE_PATH" >&2
  exit 2
fi

ARCHIVE_INFO_PLIST="$ARCHIVE_PATH/Info.plist"
if [[ ! -f "$ARCHIVE_INFO_PLIST" ]]; then
  echo "错误：找不到归档 Info.plist：$ARCHIVE_INFO_PLIST" >&2
  exit 2
fi

# 归档名：尽量从路径推导，避免依赖 Xcode 环境变量
archive_basename="$(/usr/bin/basename "$ARCHIVE_PATH")"
archive_name="${archive_basename%.xcarchive}"

# 取第一个 App（归档里通常只有一个主 App）
APP_PLIST="$(/usr/bin/find "$ARCHIVE_PATH/Products/Applications" -maxdepth 2 -name Info.plist -path "*.app/Info.plist" 2>/dev/null | /usr/bin/head -n 1 || true)"
if [[ -z "$APP_PLIST" ]]; then
  echo "错误：归档中未找到 Products/Applications/*.app/Info.plist（请先确保归档产出包含 .app）" >&2
  exit 2
fi

APP_DIR="$(/usr/bin/dirname "$APP_PLIST")"
APP_NAME="$(/usr/bin/basename "$APP_DIR")" # 例如 HeyMama.app
APP_REL_PATH="Applications/$APP_NAME"

bundle_id="$(/usr/bin/plutil -extract CFBundleIdentifier raw -o - "$APP_PLIST" 2>/dev/null || true)"
short_version="$(/usr/bin/plutil -extract CFBundleShortVersionString raw -o - "$APP_PLIST" 2>/dev/null || true)"
build_version="$(/usr/bin/plutil -extract CFBundleVersion raw -o - "$APP_PLIST" 2>/dev/null || true)"
display_name="$(/usr/bin/plutil -extract CFBundleDisplayName raw -o - "$APP_PLIST" 2>/dev/null || true)"
bundle_name="$(/usr/bin/plutil -extract CFBundleName raw -o - "$APP_PLIST" 2>/dev/null || true)"

# SchemeName 在 Organizer 中会用到，但在某些归档流程里会缺失
scheme_name="${SCHEME_NAME:-}"
if [[ -z "$scheme_name" ]]; then
  scheme_name="${archive_name:-}"
fi

if [[ -z "$bundle_id" || -z "$short_version" || -z "$build_version" ]]; then
  echo "错误：无法从 App Info.plist 读取 bundle/version/build：$APP_PLIST" >&2
  exit 2
fi

# 解析 embedded.mobileprovision（若存在）
profile_name=""
profile_uuid=""
team_id=""
provision_path="$APP_DIR/embedded.mobileprovision"
if [[ -f "$provision_path" ]]; then
  decoded="$(/usr/bin/security cms -D -i "$provision_path" 2>/dev/null || true)"
  if [[ -n "$decoded" ]]; then
    # 使用 plutil 从 xml 中提取字段
    profile_name="$(printf "%s" "$decoded" | /usr/bin/plutil -extract Name raw -o - - 2>/dev/null || true)"
    profile_uuid="$(printf "%s" "$decoded" | /usr/bin/plutil -extract UUID raw -o - - 2>/dev/null || true)"
    team_id="$(printf "%s" "$decoded" | /usr/bin/plutil -extract TeamIdentifier.0 raw -o - - 2>/dev/null || true)"
  fi
fi

# 备份一份，防止误操作
cp -f "$ARCHIVE_INFO_PLIST" "$ARCHIVE_INFO_PLIST.bak"

# 修复归档根字段，避免 Organizer 仍然把它当 Generic Archive
# 参考：标准 .xcarchive/Info.plist 通常包含 Name / SchemeName / ArchiveVersion / CreationDate 等。
# 我们只在缺失时补齐，尽量不改动归档的其他内容。
if ! /usr/bin/plutil -extract Name xml1 -o - "$ARCHIVE_INFO_PLIST" >/dev/null 2>&1; then
  /usr/bin/plutil -insert Name -string "${archive_name:-${display_name:-${bundle_name:-}}}" "$ARCHIVE_INFO_PLIST" 2>/dev/null || true
fi
if ! /usr/bin/plutil -extract SchemeName xml1 -o - "$ARCHIVE_INFO_PLIST" >/dev/null 2>&1; then
  /usr/bin/plutil -insert SchemeName -string "${scheme_name:-${archive_name:-}}" "$ARCHIVE_INFO_PLIST" 2>/dev/null || true
fi

# 如果已有 ApplicationProperties，直接更新关键字段即可
if /usr/bin/plutil -extract ApplicationProperties xml1 -o - "$ARCHIVE_INFO_PLIST" >/dev/null 2>&1; then
  /usr/bin/plutil -replace ApplicationProperties.ApplicationPath -string "$APP_REL_PATH" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -replace ApplicationProperties.CFBundleIdentifier -string "$bundle_id" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -replace ApplicationProperties.CFBundleShortVersionString -string "$short_version" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -replace ApplicationProperties.CFBundleVersion -string "$build_version" "$ARCHIVE_INFO_PLIST"
else
  # 新增 ApplicationProperties（注意：plutil 的空字典/数组类型是 -dictionary / -array）
  /usr/bin/plutil -insert ApplicationProperties -dictionary "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -insert ApplicationProperties.ApplicationPath -string "$APP_REL_PATH" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -insert ApplicationProperties.CFBundleIdentifier -string "$bundle_id" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -insert ApplicationProperties.CFBundleShortVersionString -string "$short_version" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -insert ApplicationProperties.CFBundleVersion -string "$build_version" "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -insert ApplicationProperties.Architectures -array "$ARCHIVE_INFO_PLIST"
  /usr/bin/plutil -insert ApplicationProperties.Architectures.0 -string "arm64" "$ARCHIVE_INFO_PLIST"
fi

# 可选字段：Provisioning Profile 信息（不保证一定存在）
if [[ -n "$profile_name" ]]; then
  /usr/bin/plutil -replace ApplicationProperties.ProvisioningProfileName -string "$profile_name" "$ARCHIVE_INFO_PLIST" 2>/dev/null || \
  /usr/bin/plutil -insert ApplicationProperties.ProvisioningProfileName -string "$profile_name" "$ARCHIVE_INFO_PLIST"
fi
if [[ -n "$profile_uuid" ]]; then
  /usr/bin/plutil -replace ApplicationProperties.ProvisioningProfileUUID -string "$profile_uuid" "$ARCHIVE_INFO_PLIST" 2>/dev/null || \
  /usr/bin/plutil -insert ApplicationProperties.ProvisioningProfileUUID -string "$profile_uuid" "$ARCHIVE_INFO_PLIST"
fi
if [[ -n "$team_id" ]]; then
  /usr/bin/plutil -replace ApplicationProperties.Team -string "$team_id" "$ARCHIVE_INFO_PLIST" 2>/dev/null || \
  /usr/bin/plutil -insert ApplicationProperties.Team -string "$team_id" "$ARCHIVE_INFO_PLIST"
fi

echo "已修复归档 header：$ARCHIVE_INFO_PLIST"
echo "主 App：$APP_REL_PATH"
echo "Bundle：$bundle_id"
echo "Version/Build：$short_version/$build_version"
echo "Name/SchemeName：${archive_name:-} / ${scheme_name:-}"

# 轻量自检：确保关键字段存在（不强制失败，避免中断归档）
if ! /usr/bin/plutil -extract ApplicationProperties.ApplicationPath xml1 -o - "$ARCHIVE_INFO_PLIST" >/dev/null 2>&1; then
  echo "警告：归档 Info.plist 仍缺少 ApplicationProperties.ApplicationPath，Organizer 可能仍显示 Generic Archive" >&2
fi
