#!/usr/bin/env bash
# ibit Flutter 自动打包脚本
#
# 用法:
#   ./scripts/build.sh                构建 Android + iOS Release (默认)
#   ./scripts/build.sh android        仅构建 Android Release
#   ./scripts/build.sh android-debug  仅构建 Android Debug
#   ./scripts/build.sh ios            仅构建 iOS Release
#   ./scripts/build.sh ios-adhoc      仅构建 iOS Ad-hoc
#   ./scripts/build.sh --clean        构建前先执行 flutter clean
#   ./scripts/build.sh -h             显示帮助
#
# 产物归档位置: releases/v<版本>_<时间戳>/
#   ├── app-release.apk
#   ├── *.ipa
#   ├── symbols-android/    (Dart 混淆符号,用于 flutter symbolize 反解)
#   ├── symbols-ios/        (同上)
#   └── BUILD_INFO.txt

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$PROJECT_ROOT"

RELEASES_DIR="releases"
SYMBOLS_ANDROID_DIR="build/debug-info/android"
SYMBOLS_IOS_DIR="build/debug-info/ios"

if [ -t 1 ]; then
  RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
  BLUE='\033[0;34m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'
else
  RED=''; GREEN=''; YELLOW=''; BLUE=''; CYAN=''; BOLD=''; NC=''
fi

log_info() { printf "${BLUE}==>${NC} %s\n" "$*"; }
log_ok()   { printf "${GREEN}✓${NC}  %s\n" "$*"; }
log_warn() { printf "${YELLOW}!${NC}  %s\n" "$*"; }
log_err()  { printf "${RED}✗${NC}  %s\n" "$*" >&2; }
log_step() { printf "\n${CYAN}${BOLD}▶ %s${NC}\n" "$*"; }

usage() {
  cat <<EOF
ibit Flutter 自动打包脚本

用法:
  ./scripts/build.sh [模式] [选项]

模式:
  all              构建 Android + iOS Release (默认)
  android          仅构建 Android Release
  android-debug    仅构建 Android Debug
  ios              仅构建 iOS Release
  ios-adhoc        仅构建 iOS Ad-hoc

选项:
  --clean          构建前执行 flutter clean
  -h, --help       显示此帮助

示例:
  ./scripts/build.sh                      # 同时打 Android + iOS Release
  ./scripts/build.sh android              # 只打 Android Release
  ./scripts/build.sh ios-adhoc --clean    # 清理后打 iOS Ad-hoc

产物归档位置: ${RELEASES_DIR}/v<版本>_<时间戳>/
EOF
}

MODE="all"
DO_CLEAN=false
while [ $# -gt 0 ]; do
  case "$1" in
    -h|--help) usage; exit 0 ;;
    --clean) DO_CLEAN=true ;;
    all|android|android-debug|ios|ios-adhoc) MODE="$1" ;;
    *) log_err "未知参数: $1"; echo; usage; exit 1 ;;
  esac
  shift
done

if ! command -v flutter >/dev/null 2>&1; then
  log_err "未找到 flutter 命令,请检查 PATH"
  exit 1
fi

if [ ! -f pubspec.yaml ]; then
  log_err "未在 pubspec.yaml 所在目录执行,当前: $(pwd)"
  exit 1
fi

VERSION="$(grep '^version:' pubspec.yaml | awk '{print $2}' | tr -d '[:space:]')"
if [ -z "$VERSION" ]; then
  log_err "无法从 pubspec.yaml 读取版本号"
  exit 1
fi

TIMESTAMP="$(date +%Y%m%d_%H%M)"
RELEASE_DIR="${RELEASES_DIR}/v${VERSION}_${TIMESTAMP}"

log_step "ibit 打包"
log_info "版本      : v${VERSION}"
log_info "模式      : ${MODE}"
log_info "归档目录  : ${RELEASE_DIR}"
log_info "Git 分支  : $(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'N/A')"
log_info "Git 提交  : $(git rev-parse --short HEAD 2>/dev/null || echo 'N/A')"

DIRTY_COUNT=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
if [ "$DIRTY_COUNT" -gt 0 ]; then
  log_warn "当前有 $DIRTY_COUNT 个未提交的改动,构建的产物可能包含未追踪代码"
fi

if [ "$DO_CLEAN" = true ]; then
  log_step "flutter clean"
  flutter clean
  log_ok "clean 完成"
fi

log_step "flutter pub get"
flutter pub get >/dev/null
log_ok "pub get 完成"

mkdir -p "$RELEASE_DIR"

copy_android_symbols() {
  if [ -d "$SYMBOLS_ANDROID_DIR" ] && [ "$(ls -A "$SYMBOLS_ANDROID_DIR" 2>/dev/null)" ]; then
    mkdir -p "$RELEASE_DIR/symbols-android"
    cp -r "$SYMBOLS_ANDROID_DIR"/* "$RELEASE_DIR/symbols-android/"
    log_ok "Android 符号 → $RELEASE_DIR/symbols-android/"
  fi
}

copy_ios_symbols() {
  if [ -d "$SYMBOLS_IOS_DIR" ] && [ "$(ls -A "$SYMBOLS_IOS_DIR" 2>/dev/null)" ]; then
    mkdir -p "$RELEASE_DIR/symbols-ios"
    cp -r "$SYMBOLS_IOS_DIR"/* "$RELEASE_DIR/symbols-ios/"
    log_ok "iOS 符号 → $RELEASE_DIR/symbols-ios/"
  fi
}

build_android_debug() {
  log_step "构建 Android Debug APK"
  flutter build apk --debug \
    --target-platform android-arm,android-arm64

  local apk="build/app/outputs/flutter-apk/app-debug.apk"
  if [ ! -f "$apk" ]; then
    log_err "未找到产物: $apk"
    return 1
  fi
  cp "$apk" "$RELEASE_DIR/app-debug.apk"
  local size; size=$(du -h "$apk" | cut -f1)
  log_ok "Debug APK (${size}) → $RELEASE_DIR/app-debug.apk"
}

build_android_release() {
  log_step "构建 Android Release APK"
  flutter build apk --release \
    --target-platform android-arm,android-arm64 \
    --obfuscate \
    --split-debug-info="$SYMBOLS_ANDROID_DIR"

  local apk="build/app/outputs/flutter-apk/app-release.apk"
  if [ ! -f "$apk" ]; then
    log_err "未找到产物: $apk"
    return 1
  fi
  cp "$apk" "$RELEASE_DIR/app-release.apk"
  copy_android_symbols
  local size; size=$(du -h "$apk" | cut -f1)
  log_ok "Release APK (${size}) → $RELEASE_DIR/app-release.apk"
}

build_ios_release() {
  log_step "构建 iOS Release IPA"
  flutter build ipa --release \
    --obfuscate \
    --split-debug-info="$SYMBOLS_IOS_DIR"

  local ipa
  ipa="$(find build/ios/ipa -maxdepth 1 -name "*.ipa" -type f 2>/dev/null | head -1)"
  if [ -z "$ipa" ]; then
    log_err "未找到 IPA 产物,请检查 Xcode 签名配置"
    return 1
  fi
  local dst="$RELEASE_DIR/$(basename "$ipa" .ipa)-release.ipa"
  cp "$ipa" "$dst"
  copy_ios_symbols
  local size; size=$(du -h "$ipa" | cut -f1)
  log_ok "Release IPA (${size}) → $dst"
}

build_ios_adhoc() {
  log_step "构建 iOS Ad-hoc IPA"
  flutter build ipa --release --export-method=ad-hoc \
    --obfuscate \
    --split-debug-info="$SYMBOLS_IOS_DIR"

  local ipa
  ipa="$(find build/ios/ipa -maxdepth 1 -name "*.ipa" -type f 2>/dev/null | head -1)"
  if [ -z "$ipa" ]; then
    log_err "未找到 IPA 产物,请检查 Xcode 签名配置"
    return 1
  fi
  local dst="$RELEASE_DIR/$(basename "$ipa" .ipa)-adhoc.ipa"
  cp "$ipa" "$dst"
  copy_ios_symbols
  local size; size=$(du -h "$ipa" | cut -f1)
  log_ok "Ad-hoc IPA (${size}) → $dst"
}

case "$MODE" in
  all)           build_android_release; build_ios_release ;;
  android)       build_android_release ;;
  android-debug) build_android_debug ;;
  ios)           build_ios_release ;;
  ios-adhoc)     build_ios_adhoc ;;
esac

{
  echo "版本        : v${VERSION}"
  echo "构建时间    : $(date '+%Y-%m-%d %H:%M:%S')"
  echo "构建模式    : ${MODE}"
  echo "Git 分支    : $(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'N/A')"
  echo "Git 提交    : $(git rev-parse --short HEAD 2>/dev/null || echo 'N/A')"
  echo "未提交改动  : ${DIRTY_COUNT}"
  echo ""
  echo "Flutter 版本:"
  flutter --version 2>&1 | sed 's/^/  /'
} > "$RELEASE_DIR/BUILD_INFO.txt"

log_step "完成"
log_info "归档目录: $(pwd)/${RELEASE_DIR}"
echo ""
ls -lh "$RELEASE_DIR"

if [ -f .gitignore ] && ! grep -qE "^/?releases/?$" .gitignore; then
  echo ""
  log_warn "建议将 '${RELEASES_DIR}/' 加入 .gitignore,避免构建产物进入 Git"
fi
