#!/usr/bin/env bash
# Detect Expo vs bare React Native for the configured mobile app.
# Sourced by entrypoint.sh (inside Docker) and open-mobile.sh (on the host).

mobile_repo_root() {
  if [ -n "${1:-}" ]; then
    printf '%s' "$1"
    return
  fi
  if [ -n "${FRONTEND_DIR:-}" ]; then
    case "${FRONTEND_DIR}" in
      /*) printf '%s' "${FRONTEND_DIR}" ;;
      *)  printf '%s' "${WORKSPACE_DIR:-${RUN_DIR}}/${FRONTEND_DIR#./}" ;;
    esac
    return
  fi
  printf '/app'
}

mobile_single_package_repo() {
  local root="$1"
  [ ! -f "${root}/pnpm-workspace.yaml" ] \
    && ! grep -q '"workspaces"' "${root}/package.json" 2>/dev/null
}

mobile_app_manifest() {
  local app="${1:-${MOBILE_APP:-mobile-client}}"
  local root
  root="$(mobile_repo_root "${2:-}")"

  if mobile_single_package_repo "${root}"; then
    printf '%s/package.json' "${root}"
    return 0
  fi

  local dir pkg
  for dir in "${root}"/apps/*; do
    [ -f "${dir}/package.json" ] || continue
    pkg="$(node -pe "try{JSON.parse(require('fs').readFileSync('${dir}/package.json','utf8')).name}catch(e){''}" 2>/dev/null || true)"
    if [ "${pkg}" = "${app}" ] || [ "$(basename "${dir}")" = "${app}" ]; then
      printf '%s/package.json' "${dir}"
      return 0
    fi
  done

  if [ -f "${root}/apps/${app}/package.json" ]; then
    printf '%s/apps/%s/package.json' "${root}" "${app}"
  fi
}

mobile_stack_kind() {
  local app="${1:-${MOBILE_APP:-mobile-client}}"
  local root="${2:-}"
  case "${MOBILE_STACK:-auto}" in
    expo|react-native) printf '%s' "${MOBILE_STACK}"; return 0 ;;
  esac

  local manifest
  manifest="$(mobile_app_manifest "${app}" "${root}")"
  if [ ! -f "${manifest}" ]; then
    printf 'expo'
    return 0
  fi

  node - "${manifest}" <<'NODE'
const fs = require('fs');
const manifest = process.argv[2];
const pkg = JSON.parse(fs.readFileSync(manifest, 'utf8'));
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
if ('expo' in deps) process.stdout.write('expo');
else if ('react-native' in deps) process.stdout.write('react-native');
else process.stdout.write('expo');
NODE
}

mobile_pnpm_filter() {
  local app="${1:-${MOBILE_APP:-mobile-client}}"
  local root
  root="$(mobile_repo_root "${2:-}")"
  if mobile_single_package_repo "${root}"; then
    printf 'pnpm'
    return 0
  fi
  printf 'pnpm --filter %s' "${app}"
}

mobile_run_in_frontend() {
  local app="${1:-${MOBILE_APP:-mobile-client}}"
  shift
  local root cmd
  root="$(mobile_repo_root)"
  cmd="$(mobile_pnpm_filter "${app}" "${root}")"
  (cd "${root}" && ${cmd} exec "$@")
}

workspace_has_mobile() {
  [ -d "${FRONTEND_DIR}" ] || return 1
  python3 - "${FRONTEND_DIR}" <<'PY'
import json, os, sys

root = os.path.abspath(sys.argv[1])
mobile = {"expo", "react-native"}


def is_mobile(path):
    try:
        with open(path, encoding="utf-8") as fh:
            pkg = json.load(fh)
    except (OSError, ValueError):
        return False
    deps = set(pkg.get("dependencies", {})) | set(pkg.get("devDependencies", {}))
    return bool(deps & mobile)


mono = (
    os.path.exists(os.path.join(root, "pnpm-workspace.yaml"))
    or os.path.isdir(os.path.join(root, "apps"))
)
if not mono:
    sys.exit(0 if is_mobile(os.path.join(root, "package.json")) else 1)

apps = os.path.join(root, "apps")
if not os.path.isdir(apps):
    sys.exit(1)
for name in os.listdir(apps):
    manifest = os.path.join(apps, name, "package.json")
    if is_mobile(manifest):
        sys.exit(0)
sys.exit(1)
PY
}

mobile_enabled() {
  case "${RUN_MOBILE:-auto}" in
    false|FALSE|0|no|NO|off|OFF) return 1 ;;
    true|TRUE|1|yes|YES|on|ON) return 0 ;;
  esac
  workspace_has_mobile
}

mobile_app_dir() {
  local manifest
  manifest="$(mobile_app_manifest "$@")"
  if [ -f "${manifest}" ]; then
    dirname "${manifest}"
  fi
}
