#!/usr/bin/env bash
# Local RapidKit project launcher (shared template)
# This script is generated into `my-project/.rapidkit/rapidkit`.
# It chooses the appropriate toolchain depending on project files:
#  - Python projects (pyproject.toml): prefer project .venv poetry then system poetry
#  - Node projects (package.json): prefer pnpm -> yarn -> npm
#  - `init` attempts to install dependencies for the detected package type

set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"

# Detect project type
if [ -f "$ROOT_DIR/pyproject.toml" ]; then
  PKG_TYPE="python"
elif [ -f "$ROOT_DIR/package.json" ]; then
  PKG_TYPE="node"
else
  PKG_TYPE="unknown"
fi

VENV_PY="${ROOT_DIR}/.venv/bin/python"
VENV_POETRY="${ROOT_DIR}/.venv/bin/poetry"

function pick_node_pm() {
  # prefer pnpm -> yarn -> npm if available in PATH
  if command -v pnpm >/dev/null 2>&1; then
    echo pnpm
  elif command -v yarn >/dev/null 2>&1; then
    echo yarn
  elif command -v npm >/dev/null 2>&1; then
    echo npm
  else
    echo ""
  fi
}

case "$PKG_TYPE" in
  python)
    # prefer project-local poetry
    if [ -x "$VENV_POETRY" ]; then
      if [ "${1:-}" = "init" ]; then
        # Run poetry install (do not exec so we can print follow-up hints)
        "$VENV_POETRY" install || exit $?
        echo "\n✅ Project bootstrapped (dependencies installed)."
        echo "💡 To activate in your current shell without opening a new terminal run:"
        echo '  eval "$(rapidkit shell activate)"'
        exit 0
      else
        exec "$VENV_POETRY" "run" "$@"
      fi
    fi

    # then prefer poetry on PATH
    if command -v poetry >/dev/null 2>&1; then
      if [ "${1:-}" = "init" ]; then
        # Run system poetry install and then provide an activation hint
        poetry install || exit $?
        echo "\n✅ Project bootstrapped (dependencies installed)."
        echo "💡 To activate in your current shell without opening a new terminal run:"
        echo '  eval "$(rapidkit shell activate)"'
        exit 0
      else
        exec poetry "run" "$@"
      fi
    fi

    # If venv python exists, try installing poetry into it and retry
    if [ -x "$VENV_PY" ]; then
      echo "⚠️  Poetry not found. Installing poetry into project .venv..."
      "$VENV_PY" -m pip install --upgrade pip >/dev/null 2>&1 || true
      "$VENV_PY" -m pip install poetry >/dev/null 2>&1 || true
      if [ -x "$VENV_POETRY" ]; then
        if [ "${1:-}" = "init" ]; then
          # Run poetry install inside venv and then give activation hint
          "$VENV_POETRY" install || exit $?
          echo "\n✅ Project bootstrapped (dependencies installed)."
          echo "💡 To activate in your current shell without opening a new terminal run:"
          echo '  eval "$(rapidkit shell activate)"'
          exit 0
        else
          exec "$VENV_POETRY" "run" "$@"
        fi
      else
        echo "❌ Failed to locate poetry after installation. You can run: '$VENV_PY -m pip install poetry' or 'pip install --user poetry'"
        exit 1
      fi
    fi

    echo "❌ Poetry is not available and no project .venv exists."
    echo "💡 Run: 'rapidkit init' to bootstrap the project (create .venv and install dependencies), or install poetry globally: 'pip install poetry'"
    exit 127
    ;;

  node)
    PM="$(pick_node_pm)"
    if [ -z "$PM" ]; then
      echo "❌ No supported Node package manager found (pnpm/yarn/npm). Install Node and a package manager to continue." >&2
      exit 127
    fi

    # init -> install
    if [ "${1:-}" = "init" ]; then
      # If package.json defines an engines.node, verify the current node runtime
      if [ -f "$ROOT_DIR/package.json" ]; then
        NODE_ENGINE=""
        # Try a best-effort extraction of engines.node using Python (if available)
        if command -v python >/dev/null 2>&1; then
          NODE_ENGINE=$(python -c "import json,sys
try:
    p=json.load(open('package.json'))
    print(p.get('engines', {}).get('node',''))
except Exception:
    print('')" 2>/dev/null || true)
        fi

        if [ -n "$NODE_ENGINE" ] && command -v node >/dev/null 2>&1; then
          # extract first number candidate
          REQ_MAJOR=$(echo "$NODE_ENGINE" | sed -E 's/[^0-9]/ /g' | awk '{print $1}') || true
          CUR_V=$(node --version 2>/dev/null | sed 's/^v//') || true
          CUR_MAJOR=$(echo "$CUR_V" | cut -d. -f1) || true
          if [ -n "$REQ_MAJOR" ] && [ -n "$CUR_MAJOR" ]; then
            if [ "$CUR_MAJOR" -lt "$REQ_MAJOR" ]; then
              echo "❌ Node engine mismatch: package.json requires node ${NODE_ENGINE} but system node is v${CUR_V}."
              echo "💡 Use nvm/asdf to install a compatible Node version, or run via Docker (Dockerfile targets NODE_VERSION=${NODE_VERSION:-20.19.6})."
              echo "👉 You can bypass this check with IGNORE_ENGINES=1 ./rapidkit init (not recommended)."
              exit 127
            fi
          fi
        fi
      fi
    fi
    if [ "${1:-}" = "init" ]; then
      if [ "$PM" = "npm" ]; then
        exec npm install
      elif [ "$PM" = "yarn" ]; then
        # Prefer reproducible installs, but allow lockfile updates when deps changed
        # (e.g. after RapidKit module installation updates package.json).
        yarn install --frozen-lockfile || {
          echo "⚠️  Lockfile out of date; re-running yarn install to update it." >&2
          yarn install
        }
        exit $?
      else
        # Prefer reproducible installs, but allow lockfile updates when deps changed.
        pnpm install --frozen-lockfile || {
          echo "⚠️  Lockfile out of date; re-running pnpm install to update it." >&2
          pnpm install
        }
        exit $?
      fi
    fi

    # For other commands, prefer 'run' semantics
    # We call: <pm> run <cmd> [args]
    # If package.json declares an engines.node constraint, check runtime compatibility
    if [ -f "$ROOT_DIR/package.json" ] && [ "${IGNORE_ENGINES:-0}" != "1" ]; then
      NODE_ENGINE=""
      if command -v python >/dev/null 2>&1; then
        NODE_ENGINE=$(python -c "import json,sys
try:
    p=json.load(open('package.json'))
    print(p.get('engines', {}).get('node',''))
except Exception:
    print('')" 2>/dev/null || true)
      fi

      if [ -n "$NODE_ENGINE" ] && command -v node >/dev/null 2>&1; then
        REQ_MAJOR=$(echo "$NODE_ENGINE" | sed -E 's/[^0-9]/ /g' | awk '{print $1}') || true
        CUR_V=$(node --version 2>/dev/null | sed 's/^v//') || true
        CUR_MAJOR=$(echo "$CUR_V" | cut -d. -f1) || true
        if [ -n "$REQ_MAJOR" ] && [ -n "$CUR_MAJOR" ]; then
          if [ "$CUR_MAJOR" -lt "$REQ_MAJOR" ]; then
            echo "❌ Node engine mismatch: package.json requires node ${NODE_ENGINE} but system node is v${CUR_V}."
            echo "💡 Use nvm/asdf to switch to a compatible Node version, or run via Docker (see project Dockerfile / NODE_VERSION)."
            echo "👉 You can bypass this check with IGNORE_ENGINES=1 ./rapidkit <cmd> (not recommended)."
            exit 127
          fi
        fi
      fi
    fi

    CMD="$1"
    shift || true
    exec "$PM" run "$CMD" "$@"
    ;;

  *)
    echo "❌ Could not detect project type (.venv/pyproject.toml or package.json missing)."
    echo "💡 If this is a Python project run: 'rapidkit init' to create .venv and install deps, or add a package.json for Node projects."
    exit 127
    ;;
esac
