#!/bin/bash
#
# Eazytec is pleased to support the open source community by making CPF-KMP-CMP available.
# Copyright (C) 2026 Eazytec. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
set -e

# Record script start time
START_TIME=$(date +%s)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# 与 composeApp/build.gradle.kts 中 publish*BinariesToHarmonyApp 的 into 路径一致（Gradle: rootProject.name + "." + project.name.lowercase() + ".generated.resources"）
harmony_publish_compose_resources_package() {
    local _root_name
    _root_name=$(grep -E '^\s*rootProject\.name\s*=' "$SCRIPT_DIR/settings.gradle.kts" 2>/dev/null | head -1 | sed -n 's/.*=\s*"\([^"]*\)".*/\1/p')
    [ -z "$_root_name" ] && _root_name="TestToolChainDemo"
    echo "${_root_name}.composeapp.generated.resources"
}

# 删除一次 Gradle publish 会拷入的 kn 头/so 与 composeResources 目录（由本脚本在 gradlew publish 前调用）
delete_harmony_publish_kn_outputs() {
    local _base="$1"
    _base="${_base%/}"
    [ -d "$_base/entry" ] || return 0
    local _pkg
    _pkg=$(harmony_publish_compose_resources_package)
    rm -f "$_base/entry/src/main/cpp/include/libkn_api.h" 2>/dev/null || true
    rm -f "$_base/entry/libs/arm64-v8a/libkn.so" 2>/dev/null || true
    rm -f "$_base/entry/libs/x86_64/libkn.so" 2>/dev/null || true
    rm -rf "$_base/entry/src/main/resources/rawfile/composeResources/$_pkg" 2>/dev/null || true
}

delete_all_harmony_publish_targets_before_gradle() {
    delete_harmony_publish_kn_outputs "$SCRIPT_DIR/harmonyApp"
    if [ -n "${LOCAL_OHOS_PATH:-}" ]; then
        if [[ "$LOCAL_OHOS_PATH" = /* ]]; then
            delete_harmony_publish_kn_outputs "$LOCAL_OHOS_PATH"
        else
            delete_harmony_publish_kn_outputs "$SCRIPT_DIR/$LOCAL_OHOS_PATH"
        fi
    fi
    echo -e "\033[35m已按 publish 目标清理 harmonyApp（libkn / libkn_api.h / composeResources 包目录）\033[0m"
}

# ====================== [1. Default Configuration and Parameter Parsing] ======================
DEFAULT_PLATFORM="ohosArm64"
DEFAULT_TARGET_ID="127.0.0.1:5555"
# bundle 从 harmonyApp/AppScope/app.json5 读取，不存在则用默认
DEFAULT_BUNDLE_NAME="com.example.harmonyapp"
APP_JSON5="$SCRIPT_DIR/harmonyApp/AppScope/app.json5"
if [ -f "$APP_JSON5" ]; then
    _bundle=$(grep '"bundleName"' "$APP_JSON5" 2>/dev/null | sed 's/.*"bundleName"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | head -1 | tr -d '\r')
    [ -n "$_bundle" ] && DEFAULT_BUNDLE_NAME="$_bundle"
fi
DEFAULT_ABILITY_NAME="EntryAbility"
LOCAL_OHOS_PATH=""

usage() {
    echo "Usage: $0 [options] [PLATFORM] [TARGET_ID]"
    echo ""
    echo "Parameters:"
    echo "  PLATFORM      Build platform (default: $DEFAULT_PLATFORM)"
    echo "  TARGET_ID     Device ID (default: $DEFAULT_TARGET_ID)"
    echo ""
    echo "Options:"
    echo "  -M MODES      打包类型: debug | release | all（不传 -M 时在终端用 1/2/3 选择；非终端或 RUNOHOS_NO_MENU=1 则默认 all）"
    echo "  -m MODE       Build mode: debug or release (default: debug)"
    echo "  -b BUNDLE     Set bundle name (current: $DEFAULT_BUNDLE_NAME)"
    echo "  -a ABILITY    Set Ability name (current: $DEFAULT_ABILITY_NAME)"
    echo "  -d MODE       Debug mode: debug or attach (default: attach)"
    echo "  -p PATH       Set external OHOS project path (localOhosPath)"
    echo "  -h            Show this help message"
    echo ""
    echo "Examples:"
    echo "  $0 ohosArm64 127.0.0.1:5555"
    echo "  $0 -M debug                    # 仅打 debug 包"
    echo "  $0 -M release                  # 仅打 release 包"
    echo "  $0 -M all                     # debug+release（等价于菜单选 3）"
    echo "  $0 -b com.test.app -a MainAbility"
    echo "  $0 -p /path/to/external/ohos/project"
    exit 0
}

# Preset variables
BUNDLE_NAME=$DEFAULT_BUNDLE_NAME
ABILITY_NAME=$DEFAULT_ABILITY_NAME
BUILD_MODE="debug"
BUILD_MODES_SELECT=""
M_FLAG_SET=0
DEBUG_MODE="attach"
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'   # No Color
# Parse options (supports options in any position, e.g. ohosArm64 62Q0226107024702 -m release)
POSITIONALS=()
while [[ $# -gt 0 ]]; do
    case $1 in
        -M) M_FLAG_SET=1; BUILD_MODES_SELECT="$2"; shift 2 ;;
        -m) BUILD_MODE="$2"; shift 2 ;;
        -b) BUNDLE_NAME="$2"; shift 2 ;;
        -a) ABILITY_NAME="$2"; shift 2 ;;
        -d) DEBUG_MODE="$2"; shift 2 ;;
        -p) LOCAL_OHOS_PATH="$2"; shift 2 ;;
        -h) usage ;;
        -*)
            echo "Unknown option: $1"
            usage
            ;;
        *)
            POSITIONALS+=("$1")
            shift
            ;;
    esac
done

PLATFORM=${POSITIONALS[0]:-$DEFAULT_PLATFORM}
TARGET_ID=${POSITIONALS[1]:-$DEFAULT_TARGET_ID}

echo -e "\033[32m▶ Run environment configuration:\033[0m"
echo "  - Platform: $PLATFORM"
echo "  - Devices: from hdc list targets (see below)"
echo "  - Build modes: 由 -M 或菜单 1/2/3 选择 (debug / release / debug+release)"
echo "  - Debug mode: $DEBUG_MODE"
echo "  - Bundle: $BUNDLE_NAME"
echo "  - Ability: $ABILITY_NAME"
if [ -n "$LOCAL_OHOS_PATH" ]; then
    echo "  - External OHOS path: $LOCAL_OHOS_PATH"
fi
echo "------------------------------------------------------------"

# --- Configuration ---
DEVECO_PATH="${DEVECO_PATH:-/Applications/DevEco-Studio.app}"
MIN_VERSION="6.0.0"
echo " DevEco Studio Path ${DEVECO_PATH}"
echo "🔍 Checking environment configuration..."

# 1. Check if DevEco exists
if [ ! -d "$DEVECO_PATH" ]; then
    echo "❌ Error: DevEco Studio not found at $DEVECO_PATH."
    exit 1
fi

# 2. Get version (from Info.plist CFBundleShortVersionString)
# Output example: 5.0.3.406
CURRENT_VERSION=$(defaults read "$DEVECO_PATH/Contents/Info.plist" CFBundleShortVersionString)

echo "Current DevEco version: $CURRENT_VERSION"
echo "Minimum required version: $MIN_VERSION"
CUR_MAJOR=$(echo "$CURRENT_VERSION" | cut -d. -f1)
CUR_MINOR=$(echo "$CURRENT_VERSION" | cut -d. -f2)

REQ_MAJOR=$(echo "$MIN_VERSION" | cut -d. -f1)
REQ_MINOR=$(echo "$MIN_VERSION" | cut -d. -f2)

if [ "$CUR_MAJOR" -lt "$REQ_MAJOR" ] 2>/dev/null || \
   { [ "$CUR_MAJOR" -eq "$REQ_MAJOR" ] && [ "$CUR_MINOR" -lt "$REQ_MINOR" ]; }; then
echo "-------------------------------------------------------"
echo -e "${RED}⛔️ Error: DevEco version is too low!${NC}"
echo -e "${RED}Current version: $CURRENT_VERSION${NC}"
echo -e "${RED}Minimum required: $MIN_VERSION+${NC}"
echo -e "${RED}Please upgrade DevEco Studio and run this script again.${NC}"
echo "-------------------------------------------------------"
exit 5
fi

echo "✅ DevEco version meets requirements ($CURRENT_VERSION)"
# ====================== [2. Environment Path and SDK Configuration] ======================
DEVECO_HOME="${DEVECO_HOME:-$DEVECO_PATH/Contents}"
echo "✅  ($DEVECO_HOME)"
HDC_BIN="$DEVECO_HOME/sdk/default/openharmony/toolchains/hdc"
export DEVECO_SDK_HOME="$DEVECO_HOME/sdk"
export PATH="$DEVECO_SDK_HOME:$DEVECO_HOME/jbr/Contents/Home/bin:$DEVECO_HOME/tools/node/bin:$DEVECO_HOME/tools/ohpm/bin:$DEVECO_HOME/tools/hvigor/bin:$PATH"

# ====================== [2.5 Device List and Build Mode List] ======================
DEVICE_IDS=()
while IFS= read -r line; do
    line=$(echo "$line" | tr -d '\r' | xargs)
    [ -n "$line" ] && DEVICE_IDS+=("$line")
done < <("$HDC_BIN" list targets 2>/dev/null | awk '{if (NF>=1) print $1}')

# 打包类型：未传 -M 时在交互终端用 1/2/3 选择；CI / 管道输入用 RUNOHOS_NO_MENU=1 或默认 all
pick_build_modes_interactive() {
    if [[ -n "${RUNOHOS_NO_MENU:-}" ]]; then
        BUILD_MODES_SELECT="all"
        return
    fi
    if [[ ! -t 0 ]]; then
        BUILD_MODES_SELECT="all"
        return
    fi
    echo ""
    echo "请选择打包类型（输入数字后回车）:"
    echo "  1) 仅 debug"
    echo "  2) 仅 release"
    echo "  3) debug + release（全部）"
    local _c
    read -r -p "请输入 1 / 2 / 3 [默认 3]: " _c || true
    _c=${_c:-3}
    case "$_c" in
        1) BUILD_MODES_SELECT=debug ;;
        2) BUILD_MODES_SELECT=release ;;
        3) BUILD_MODES_SELECT=all ;;
        *) echo "无效输入，使用默认 3（debug+release）"; BUILD_MODES_SELECT=all ;;
    esac
}

if [[ "$M_FLAG_SET" -eq 0 ]]; then
    pick_build_modes_interactive
fi
if [ -z "$BUILD_MODES_SELECT" ]; then
    BUILD_MODES_SELECT="all"
fi
case "$(echo "$BUILD_MODES_SELECT" | tr '[:upper:]' '[:lower:]')" in
    debug)   BUILD_MODES=(debug) ;;
    release) BUILD_MODES=(release) ;;
    all|*)   BUILD_MODES=(debug release) ;;
esac

if [ ${#DEVICE_IDS[@]} -eq 0 ]; then
    echo -e "\033[31mError: No device found. Run 'hdc list targets' to check connected devices.\033[0m"
    exit 5
fi
echo "Devices: ${DEVICE_IDS[*]}"
echo "Build modes: ${BUILD_MODES[*]}"
echo "------------------------------------------------------------"

TOTAL_COUNT=0
SUCCESS_COUNT=0
ERR_MSGS=()
PUSH_TIMES=()
PACK_SIZES=()
set +e
for TARGET_ID in "${DEVICE_IDS[@]}"; do
for BUILD_MODE in "${BUILD_MODES[@]}"; do
((TOTAL_COUNT++))
echo ""
echo "$TARGET_ID 设备 $BUILD_MODE 模式 进行打包"
# 每轮切到项目根，与原脚本一致在项目根执行 gradlew
cd "$SCRIPT_DIR"

# 每轮打包前：先删除 entry/builds、entry/build（含 HAP）、entry/libs 下全部 .so 与 arm64-v8a/x86_64 目录，删除后检测再打包
ENTRY_BASE="$SCRIPT_DIR/harmonyApp/entry"
CHECK_BASE="$SCRIPT_DIR/harmonyApp"
HAP_PATH="$CHECK_BASE/entry/build/default/outputs/default/entry-default-signed.hap"
LIBS_ARM="$CHECK_BASE/entry/libs/arm64-v8a"
LIBS_X86="$CHECK_BASE/entry/libs/x86_64"

DEL_RETRY=0
while true; do
    rm -rf "$ENTRY_BASE/builds"
    rm -rf "$ENTRY_BASE/build"
    if [ -d "$ENTRY_BASE/libs" ]; then
        find "$ENTRY_BASE/libs" -type f \( -name '*.so' -o -name '*.SO' \) -delete 2>/dev/null || true
    fi
    rm -rf "$ENTRY_BASE/libs/arm64-v8a"
    rm -rf "$ENTRY_BASE/libs/x86_64"
    HAP_EXISTS="无"; [ -f "$HAP_PATH" ] && HAP_EXISTS="有"
    LIBS_EXISTS="无"
    if [ -d "$LIBS_ARM" ] || [ -d "$LIBS_X86" ]; then LIBS_EXISTS="有"; fi
    if [ -d "$ENTRY_BASE/libs" ]; then
        _any_so=$(find "$ENTRY_BASE/libs" -type f \( -name '*.so' -o -name '*.SO' \) 2>/dev/null | head -1)
        [ -n "$_any_so" ] && LIBS_EXISTS="有"
    fi
    if [ "$HAP_EXISTS" = "无" ] && [ "$LIBS_EXISTS" = "无" ]; then
        echo -e "\033[35m删除后检测: HAP包=无, libs中间产物=无，已确认清理完成\033[0m"
        break
    fi
    DEL_RETRY=$((DEL_RETRY + 1))
    if [ $DEL_RETRY -ge 5 ]; then
        _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：清理未完全，HAP包=${HAP_EXISTS}, libs中间产物=${LIBS_EXISTS}，须清光后再打包）"
        echo "$_e"
        ERR_MSGS+=("$_e")
        continue 2
    fi
    sleep 1
done

"$HDC_BIN" -t "$TARGET_ID" shell aa force-stop "$BUNDLE_NAME" >/dev/null 2>&1 || true

# ====================== [3. Gradle Build] ======================
# publish 必须跑完且成功，再进行打包、推包；命令失败时打印完整错误输出（含具体文件/配置报错）
GRADLE_OUT="/tmp/runOhos_gradle_$$.out"
GRADLE_RET=0
if [ "$PLATFORM" = "ohosArm64" ]; then
    delete_all_harmony_publish_targets_before_gradle
    if [ "$BUILD_MODE" = "release" ]; then
        echo ">>> :composeApp:publishReleaseBinariesToHarmonyApp"
        if [ -n "$LOCAL_OHOS_PATH" ]; then
            ./gradlew :composeApp:publishReleaseBinariesToHarmonyApp -PharmonyAppPath="$LOCAL_OHOS_PATH" 2>&1 | tee "$GRADLE_OUT"
        else
            ./gradlew :composeApp:publishReleaseBinariesToHarmonyApp 2>&1 | tee "$GRADLE_OUT"
        fi
        GRADLE_RET=${PIPESTATUS[0]}
    else
        echo ">>> :composeApp:publishDebugBinariesToHarmonyApp"
        if [ -n "$LOCAL_OHOS_PATH" ]; then
            ./gradlew :composeApp:publishDebugBinariesToHarmonyApp -PharmonyAppPath="$LOCAL_OHOS_PATH" 2>&1 | tee "$GRADLE_OUT"
        else
            ./gradlew :composeApp:publishDebugBinariesToHarmonyApp 2>&1 | tee "$GRADLE_OUT"
        fi
        GRADLE_RET=${PIPESTATUS[0]}
    fi
elif [ "$PLATFORM" = "ohosX86_64" ]; then
    delete_all_harmony_publish_targets_before_gradle
    if [ "$BUILD_MODE" = "release" ]; then
        echo ">>> :composeApp:publishReleaseBinariesToHarmonyApp"
        if [ -n "$LOCAL_OHOS_PATH" ]; then
            ./gradlew :composeApp:publishReleaseBinariesToHarmonyApp -PharmonyAppPath="$LOCAL_OHOS_PATH" 2>&1 | tee "$GRADLE_OUT"
        else
            ./gradlew :composeApp:publishReleaseBinariesToHarmonyApp 2>&1 | tee "$GRADLE_OUT"
        fi
        GRADLE_RET=${PIPESTATUS[0]}
    else
        echo ">>> :composeApp:publishDebugBinariesToHarmonyApp"
        if [ -n "$LOCAL_OHOS_PATH" ]; then
            ./gradlew :composeApp:publishDebugBinariesToHarmonyApp -PharmonyAppPath="$LOCAL_OHOS_PATH" 2>&1 | tee "$GRADLE_OUT"
        else
            ./gradlew :composeApp:publishDebugBinariesToHarmonyApp 2>&1 | tee "$GRADLE_OUT"
        fi
        GRADLE_RET=${PIPESTATUS[0]}
    fi

elif [ "$PLATFORM" = "iosSimulatorArm64" ]; then
    echo ">>> :composeApp:linkDebugFrameworkIosSimulatorArm64"
    ./gradlew :composeApp:linkDebugFrameworkIosSimulatorArm64 2>&1 | tee "$GRADLE_OUT"
    GRADLE_RET=${PIPESTATUS[0]}
else
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：不支持的平台 $PLATFORM）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    continue
fi
if [ $GRADLE_RET -ne 0 ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：Gradle publish 未成功，exit code $GRADLE_RET）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    echo "  >>> 命令错误输出（含具体文件/配置报错）:"
    [ -f "$GRADLE_OUT" ] && cat "$GRADLE_OUT" | tail -80
    rm -f "$GRADLE_OUT"
    continue
fi
rm -f "$GRADLE_OUT"
# SO packaging end time
HAP_START_TIME=$(date +%s)
# --- Subsequent install logic (hdc install etc.) ---
# ====================== [4. HAP Package Build] ======================
# Switch to harmonyApp directory for subsequent OHOS commands
# Use external path if specified, otherwise use default harmonyApp directory
if [ -n "$LOCAL_OHOS_PATH" ]; then
    HARMONY_APP_DIR="$LOCAL_OHOS_PATH"
else
    HARMONY_APP_DIR="harmonyApp"
fi

if [ ! -d "$HARMONY_APP_DIR" ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：harmonyApp 目录不存在 $HARMONY_APP_DIR）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    continue
fi
cd "$HARMONY_APP_DIR"
HVIGOR_OUT="/tmp/runOhos_hvigor_$$.out"
ohpm install --all 2>&1 | tee "$HVIGOR_OUT"
OHPM_RET=${PIPESTATUS[0]}
if [ $OHPM_RET -ne 0 ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：ohpm install 失败）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    echo "  >>> 命令错误输出:"
    [ -f "$HVIGOR_OUT" ] && cat "$HVIGOR_OUT" | tail -80
    rm -f "$HVIGOR_OUT"
    cd "$SCRIPT_DIR"
    continue
fi
rm -f "$HVIGOR_OUT"

node "$DEVECO_HOME/tools/hvigor/bin/hvigorw.js" --sync -p product=default -p buildMode="$BUILD_MODE" --analyze=normal --parallel --incremental --daemon 2>&1 | tee "$HVIGOR_OUT"
HVIGOR_SYNC_RET=${PIPESTATUS[0]}
if [ $HVIGOR_SYNC_RET -ne 0 ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：hvigor --sync 失败，请查看下方输出中的文件/配置名）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    echo "  >>> 命令错误输出:"
    [ -f "$HVIGOR_OUT" ] && cat "$HVIGOR_OUT" | tail -80
    rm -f "$HVIGOR_OUT"
    cd "$SCRIPT_DIR"
    continue
fi
rm -f "$HVIGOR_OUT"

if [ "$BUILD_MODE" = "release" ]; then
    node "$DEVECO_HOME/tools/hvigor/bin/hvigorw.js" --mode module -p module=entry -p product=default -p buildMode=release -p requiredDeviceType=phone assembleHap compileNative --analyze=normal --parallel --incremental --daemon 2>&1 | tee "$HVIGOR_OUT"
else
    node "$DEVECO_HOME/tools/hvigor/bin/hvigorw.js" --mode module -p module=entry@default -p product=default -p buildMode=debug -p requiredDeviceType=phone assembleHap --analyze=normal --parallel --incremental --daemon 2>&1 | tee "$HVIGOR_OUT"
fi
HVIGOR_ASM_RET=${PIPESTATUS[0]}
if [ $HVIGOR_ASM_RET -ne 0 ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：hvigor assembleHap 失败，请查看下方输出中的文件/配置名）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    echo "  >>> 命令错误输出:"
    [ -f "$HVIGOR_OUT" ] && cat "$HVIGOR_OUT" | tail -80
    rm -f "$HVIGOR_OUT"
    cd "$SCRIPT_DIR"
    continue
fi
rm -f "$HVIGOR_OUT"

# ====================== [5. Install and Push Debug Components] ======================
AVAILABLE_TARGETS=$("$HDC_BIN" list targets)
HAP_DIR="./entry/build/default/outputs/default"
SIGNED_HAP="entry-default-signed.hap"
HAP_FILE="$HAP_DIR/$SIGNED_HAP"
# Check if signed HAP package exists
if [ ! -f "$HAP_FILE" ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：未找到已签名 HAP 包 $HAP_FILE）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    cd "$SCRIPT_DIR"
    continue
fi
if ! echo "$AVAILABLE_TARGETS" | grep -q "$TARGET_ID"; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：设备离线或未连接）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    cd "$SCRIPT_DIR"
    continue
fi

# 推包：与原脚本一致，使用绝对路径避免当前目录影响
HAP_FILE_ABS="$(pwd)/entry/build/default/outputs/default/$SIGNED_HAP"
# 安装前先卸载，避免同设备 debug/release 签名冲突（原脚本单次运行无此问题）
"$HDC_BIN" -t "$TARGET_ID" shell bm uninstall -n "$BUNDLE_NAME" >/dev/null 2>&1 || true

REMOTE_HAP_DIR="/data/local/tmp/debug_install"
"$HDC_BIN" -t "$TARGET_ID" shell mkdir -p "$REMOTE_HAP_DIR"
"$HDC_BIN" -t "$TARGET_ID" file send "$HAP_FILE_ABS" "$REMOTE_HAP_DIR"

INSTALL_OUTPUT=$("$HDC_BIN" -t "$TARGET_ID" shell bm install -p "$REMOTE_HAP_DIR/$SIGNED_HAP" 2>&1)
sleep 1
INSTALL_RESULT=$?
if echo "$INSTALL_OUTPUT" | grep -qE "failed|Failed|error|Error"; then
    "$HDC_BIN" -t "$TARGET_ID" shell bm uninstall -n "$BUNDLE_NAME" >/dev/null 2>&1 || true
    sleep 5
    INSTALL_OUTPUT=$("$HDC_BIN" -t "$TARGET_ID" shell bm install -p "$REMOTE_HAP_DIR/$SIGNED_HAP" 2>&1)
    sleep 5
fi
if echo "$INSTALL_OUTPUT" | grep -qE "failed|Failed|error|Error"; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：安装失败 bm install）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    echo "  >>> $INSTALL_OUTPUT"
    cd "$SCRIPT_DIR"
    continue
fi
# ====================== [6. App Launch and Debug Mount] ======================
"$HDC_BIN" -t "$TARGET_ID" shell rm -rf "$REMOTE_HAP_DIR" >/dev/null 2>&1
sleep 1

# Step 1: Start app (with -D if debug mode enabled)
if [ "$DEBUG_MODE" = "debug" ]; then
    AA_START_OUTPUT=$("$HDC_BIN" -t "$TARGET_ID" shell aa start -a "$ABILITY_NAME" -b "$BUNDLE_NAME" -D 2>&1)
else
    AA_START_OUTPUT=$("$HDC_BIN" -t "$TARGET_ID" shell aa start -a "$ABILITY_NAME" -b "$BUNDLE_NAME" 2>&1)
fi
# Package push complete time
END_TIME=$(date +%s)

AA_START_RESULT=$?
# Check if screen lock error
if echo "$AA_START_OUTPUT" | grep -q "10106102\|screen is locked"; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：设备屏幕已锁定，请解锁后重试）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    cd "$SCRIPT_DIR"
    continue
fi

# Step 2: Get app PID
get_pid_func() {
    "$HDC_BIN" -t "$TARGET_ID" shell "pidof $BUNDLE_NAME" 2>/dev/null | tr -d '\r' | tr -d '\n' | awk '{print $1}'
}

MAX_WAIT=45
COUNT=0
APP_PID=""
while [ $COUNT -lt $MAX_WAIT ]; do
    APP_PID=$(get_pid_func)
    if [[ "$APP_PID" =~ ^[0-9]+$ ]]; then
        break
    fi
    sleep 1
    let COUNT=COUNT+1
done

if [ -z "$APP_PID" ]; then
    _e="错误的 $TARGET_ID 设备 $BUILD_MODE 模式（原因：应用在 ${MAX_WAIT}s 内未启动，请检查设备与安装结果）"
    echo "$_e"
    ERR_MSGS+=("$_e")
    echo "  >>> aa start 输出: $AA_START_OUTPUT"
    cd "$SCRIPT_DIR"
    continue
fi

# 本组耗时统计（SO 构建 / HAP 打包+推包 / 总耗时）
ELAPSED_SO=$((HAP_START_TIME - START_TIME))
ELAPSED_HAP_PUSH=$((END_TIME - HAP_START_TIME))
ELAPSED_TOTAL=$((END_TIME - START_TIME))
echo "  - SO build time: $((ELAPSED_SO/60))m$((ELAPSED_SO%60))s (${ELAPSED_SO}s)"
echo "  - HAP package and push time: $((ELAPSED_HAP_PUSH/60))m$((ELAPSED_HAP_PUSH%60))s (${ELAPSED_HAP_PUSH}s)"
echo "  - Total time: $((ELAPSED_TOTAL/60))m$((ELAPSED_TOTAL%60))s (${ELAPSED_TOTAL}s)"

# 本组 HAP 包大小检测（当前目录为 harmonyApp）
HAP_PATH_SIZE="$(pwd)/entry/build/default/outputs/default/$SIGNED_HAP"
if [ -f "$HAP_PATH_SIZE" ]; then
    _bytes=$(stat -f%z "$HAP_PATH_SIZE" 2>/dev/null || stat -c%s "$HAP_PATH_SIZE" 2>/dev/null)
    if [ -n "$_bytes" ] && [ "$_bytes" -gt 0 ] 2>/dev/null; then
        if [ "$_bytes" -ge 1048576 ]; then
            _size_str="$((_bytes / 1048576))MB (${_bytes}B)"
        elif [ "$_bytes" -ge 1024 ]; then
            _size_str="$((_bytes / 1024))KB (${_bytes}B)"
        else
            _size_str="${_bytes}B"
        fi
        echo "  - HAP 包大小: $_size_str"
        PACK_SIZES+=("$TARGET_ID | $BUILD_MODE | $_size_str")
    fi
fi

PUSH_TIMES+=("$TARGET_ID | $BUILD_MODE | SO:${ELAPSED_SO}s HAP+push:${ELAPSED_HAP_PUSH}s 总:${ELAPSED_TOTAL}s")

echo "$TARGET_ID 设备 $BUILD_MODE 模式 打包成功"
((SUCCESS_COUNT++))

# Return to project root for next iteration (Gradle runs from project root)
cd "$SCRIPT_DIR"
done
done
set -e
SCRIPT_END_TIME=$(date +%s)

# ====================== [7. Packing Result Statistics] ======================
echo ""
echo "=============================================="
echo -e "\033[32m▶ 打包结果统计 / Packing Result Summary\033[0m"
echo "=============================================="
echo "  总次数 Total:     $TOTAL_COUNT"
echo "  推包成功 Success: $SUCCESS_COUNT"
if [ "$TOTAL_COUNT" -gt 0 ]; then
    RATE_PCT=$((SUCCESS_COUNT * 100 / TOTAL_COUNT))
    echo "  通过率 Rate:      ${SUCCESS_COUNT}/${TOTAL_COUNT} = ${RATE_PCT}%"
else
    echo "  通过率 Rate:      N/A"
fi
echo "  脚本总耗时:       $((SCRIPT_END_TIME - START_TIME))s"
echo "=============================================="

if [ ${#ERR_MSGS[@]} -gt 0 ]; then
    echo ""
    echo "----------------------------------------------"
    echo -e "\033[33m▶ 错误信息汇总\033[0m"
    echo "----------------------------------------------"
    for _line in "${ERR_MSGS[@]}"; do
        echo "  $_line"
    done
    echo "----------------------------------------------"
fi

if [ ${#PUSH_TIMES[@]} -gt 0 ]; then
    echo ""
    echo "----------------------------------------------"
    echo -e "\033[32m▶ Push Time 汇总\033[0m"
    echo "----------------------------------------------"
    for _line in "${PUSH_TIMES[@]}"; do
        echo "  $_line"
    done
    echo "----------------------------------------------"
fi

if [ ${#PACK_SIZES[@]} -gt 0 ]; then
    echo ""
    echo "----------------------------------------------"
    echo -e "\033[32m▶ 包大小汇总\033[0m"
    echo "----------------------------------------------"
    for _line in "${PACK_SIZES[@]}"; do
        echo "  $_line"
    done
    echo "----------------------------------------------"
fi
echo ""