#!/usr/bin/env bash
# CI pipeline entry: optional git checkout, native, gradle, OTA publish.
#
# Env:
#   GRADLE_TASK          assembleDebug | assembleRelease | testDebugUnitTest | …
#   RUN_UNIT_TESTS       1 (default) | 0
#   RUN_NATIVE           1 (default) | 0
#   RUN_APK              1 (default) | 0 — set 0 for tests-only
#   OTA_BASE_URL         public base for v0/ota (empty = skip OTA)
#   OTA_CHANNEL          stable | staging | dev | nightly | custom name
#   AUTO_OTA             1 to emit OTA tree under OUT_DIR
#   OUT_DIR              artifact root (default ./out/builds/$BUILD_ID)
#   BUILD_ID             build record id
#   GIT_REF              branch | tag | commit to checkout before build
set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"

BUILD_ID="${BUILD_ID:-local}"
OUT_DIR="${OUT_DIR:-${ROOT}/out/builds/${BUILD_ID}}"
GRADLE_TASK="${GRADLE_TASK:-assembleDebug}"
RUN_UNIT_TESTS="${RUN_UNIT_TESTS:-1}"
RUN_NATIVE="${RUN_NATIVE:-1}"
RUN_APK="${RUN_APK:-1}"
OTA_CHANNEL="${OTA_CHANNEL:-staging}"
AUTO_OTA="${AUTO_OTA:-0}"

mkdir -p "$OUT_DIR"
exec > >(tee -a "${OUT_DIR}/build.log") 2>&1

echo "==> Phase: init build_id=${BUILD_ID} channel=${OTA_CHANNEL}"

if [[ -n "${GIT_REF:-}" ]]; then
  echo "==> Phase: git checkout ${GIT_REF}"
  git fetch --all --tags 2>/dev/null || true
  git checkout --force "$GIT_REF"
  if [[ -n "${GIT_SHA:-}" ]]; then
    git reset --hard "$GIT_SHA"
  fi
fi

export ANDROIDCAST_ROOT="$ROOT"
export ANDROIDCAST_CCACHE="${ANDROIDCAST_CCACHE:-1}"
GRADLE_JAVA_OPT=()
if [[ -n "${JAVA_HOME:-}" ]]; then
  GRADLE_JAVA_OPT=(-Dorg.gradle.java.home="${JAVA_HOME}")
fi
# shellcheck source=android-ndk.sh
source "$ROOT/scripts/android-ndk.sh"
export ANDROID_NDK_HOME="$(androidcast_find_ndk_root "$ROOT")"
export ANDROID_NDK_ROOT="$ANDROID_NDK_HOME"
if [[ -n "${ANDROID_SDK_ROOT:-}" ]]; then
  LOCAL_PROPS="$ROOT/local.properties"
  LOCAL_PROPS_BACKUP=""
  if [[ -f "$LOCAL_PROPS" ]]; then
    LOCAL_PROPS_BACKUP="$(mktemp)"
    cp -f "$LOCAL_PROPS" "$LOCAL_PROPS_BACKUP"
  fi
  trap 'if [[ -n "${LOCAL_PROPS_BACKUP:-}" && -f "${LOCAL_PROPS_BACKUP}" ]]; then cp -f "${LOCAL_PROPS_BACKUP}" "$LOCAL_PROPS"; rm -f "${LOCAL_PROPS_BACKUP}"; else rm -f "$LOCAL_PROPS"; fi' EXIT
  printf 'sdk.dir=%s\n' "${ANDROID_SDK_ROOT//\\/\\\\}" > "$LOCAL_PROPS"
fi

echo "==> Phase: third-party submodules (libvpx, opus, speex, wireguard-android)"
bash "$ROOT/scripts/init-third-party-submodules.sh"

if [[ "$RUN_NATIVE" == "1" && "$RUN_APK" == "1" ]]; then
  echo "==> Phase: native codecs"
  ABIS="${ANDROIDCAST_CI_ABIS:-armeabi-v7a arm64-v8a x86_64}"
  rm -rf "$ROOT/build/native"
  mkdir -p "$ROOT/build/native"
  for abi in $ABIS; do
    ./scripts/build-native-codecs.sh "$abi"
  done
else
  echo "==> Phase: native codecs (skipped)"
fi

# Avoid host-specific CMake cache paths when running in Docker.
rm -rf "$ROOT/app/.cxx" "$ROOT/app/build/.cxx" "$ROOT/app/build/intermediates/cxx"
rm -rf "$ROOT/gradle/wireguard-tunnel/.cxx" "$ROOT/gradle/wireguard-tunnel/build" 2>/dev/null || true

WG_HEAD="$(git -C "$ROOT/third-party/wireguard-android" rev-parse --short HEAD 2>/dev/null || echo unknown)"
echo "==> Phase: wireguard-android (:tunnel) third-party/wireguard-android @ ${WG_HEAD}"

if [[ "$RUN_APK" == "1" ]]; then
  echo "==> Phase: gradle :tunnel + ${GRADLE_TASK}"
  if [[ "$RUN_UNIT_TESTS" == "1" ]]; then
    ./gradlew --no-daemon "${GRADLE_JAVA_OPT[@]}" clean :tunnel:assembleDebug "${GRADLE_TASK}" testDebugUnitTest
  else
    ./gradlew --no-daemon "${GRADLE_JAVA_OPT[@]}" clean :tunnel:assembleDebug "${GRADLE_TASK}"
  fi
else
  echo "==> Phase: gradle tests-only (:tunnel + testDebugUnitTest)"
  ./gradlew --no-daemon "${GRADLE_JAVA_OPT[@]}" :tunnel:assembleDebug testDebugUnitTest
fi

APK=""
if [[ "$RUN_APK" == "1" ]]; then
  for candidate in \
    "$ROOT/app/build/outputs/apk/debug/app-debug.apk" \
    "$ROOT/app/build/outputs/apk/release/app-release-unsigned.apk" \
    "$ROOT/app/build/outputs/apk/release/app-release.apk"; do
    if [[ -f "$candidate" ]]; then
      APK="$candidate"
      break
    fi
  done
  if [[ -z "$APK" ]]; then
    echo "ERROR: no APK produced" >&2
    exit 1
  fi
  cp -f "$APK" "${OUT_DIR}/android_cast-latest.apk"
  echo "==> APK: ${OUT_DIR}/android_cast-latest.apk"
fi

if [[ "$AUTO_OTA" == "1" && -n "${OTA_BASE_URL:-}" && -n "$APK" ]]; then
  echo "==> Phase: OTA publish channel=${OTA_CHANNEL}"
  OTA_PUBLISH="${OUT_DIR}/ota-publish"
  rm -rf "$OTA_PUBLISH"
  ./scripts/generate-ota-v0.sh "$APK" "$OTA_BASE_URL" "$OTA_PUBLISH" "$OTA_CHANNEL"
  mkdir -p "${OUT_DIR}/ota"
  cp -rf "${OTA_PUBLISH}/v0" "${OUT_DIR}/ota/"
  for ch in staging dev nightly stable; do
    if [[ "$OTA_CHANNEL" == "$ch" ]]; then
      continue
    fi
    if [[ "$OTA_CHANNEL" == "stable" || "$OTA_CHANNEL" == "prod" || "$OTA_CHANNEL" == "production" || "$OTA_CHANNEL" == "release" ]]; then
      ./scripts/generate-ota-v0.sh "$APK" "$OTA_BASE_URL" "${OUT_DIR}/ota-publish-${ch}" "$ch" || true
      mkdir -p "${OUT_DIR}/ota-${ch}"
      cp -rf "${OUT_DIR}/ota-publish-${ch}/v0" "${OUT_DIR}/ota-${ch}/" 2>/dev/null || true
    fi
  done
fi

cat >"${OUT_DIR}/BUILD_INFO.json" <<EOF
{
  "buildId": "${BUILD_ID}",
  "gradleTask": "${GRADLE_TASK}",
  "otaChannel": "${OTA_CHANNEL}",
  "apk": "android_cast-latest.apk",
  "gitSha": "$(git -C "$ROOT" rev-parse HEAD 2>/dev/null || echo unknown)",
  "gitRef": "${GIT_REF:-}",
  "ciVersion": "${ANDROIDCAST_CI_VERSION:-00.01.00.1000}"
}
EOF

echo "==> Phase: done"

# Mounted-repo Docker runs must not leave /opt/android-sdk paths in app/.cxx on the host.
rm -rf "$ROOT/app/.cxx"
