#!/usr/bin/env sh
set -eu

MAYA_WORKER_DOWNLOAD_BASE_URL="${MAYA_WORKER_DOWNLOAD_BASE_URL:-https://www.mayaai.top/downloads/maya-worker}"
MAYA_WORKER_REPO_WEB_URL="${MAYA_WORKER_REPO_WEB_URL:-}"
MAYA_CLI_INSTALL_DIR="${MAYA_CLI_INSTALL_DIR:-${MAYA_WORKER_INSTALL_DIR:-$HOME/.maya/bin}}"
MAYA_WORKER_INSTALL_DIR="$MAYA_CLI_INSTALL_DIR"
MAYA_CLI_SHIM_DIR="${MAYA_CLI_SHIM_DIR:-/usr/local/bin}"
MAYA_WORKER_GITHUB_TOKEN="${MAYA_WORKER_GITHUB_TOKEN:-}"
MAYA_WORKER_ARCHIVE_FILE="${MAYA_WORKER_ARCHIVE_FILE:-}"

info() {
  printf '%s\n' "==> $*"
}

ok() {
  printf '%s\n' "OK: $*"
}

fail() {
  printf '%s\n' "ERROR: $*" >&2
  exit 1
}

command_exists() {
  command -v "$1" >/dev/null 2>&1
}

curl_with_auth() {
  if [ -n "$MAYA_WORKER_GITHUB_TOKEN" ]; then
    curl -H "Authorization: Bearer $MAYA_WORKER_GITHUB_TOKEN" "$@"
  else
    curl "$@"
  fi
}

require_node() {
  command_exists node || fail "Node.js 20 or newer is required to run Maya worker. Install Node.js from https://nodejs.org/ and rerun this installer."

  node_major="$(node -p 'Number(process.versions.node.split(".")[0])' 2>/dev/null || true)"
  case "$node_major" in
    ''|*[!0-9]*)
      fail "Could not determine Node.js version. Install Node.js 20 or newer from https://nodejs.org/ and rerun this installer."
      ;;
  esac

  if [ "$node_major" -lt 20 ]; then
    current_version="$(node -v 2>/dev/null || printf 'unknown')"
    fail "Node.js 20 or newer is required to run Maya worker. Current Node.js version is ${current_version}."
  fi
}

detect_os_arch() {
  case "$(uname -s)" in
    Darwin) OS="darwin" ;;
    Linux) OS="linux" ;;
    *) fail "Unsupported operating system: $(uname -s). Maya worker supports macOS and Linux." ;;
  esac

  case "$(uname -m)" in
    x86_64|amd64) ARCH="amd64" ;;
    arm64|aarch64) ARCH="arm64" ;;
    *) fail "Unsupported architecture: $(uname -m)." ;;
  esac
}

get_latest_version() {
  if [ -n "$MAYA_WORKER_REPO_WEB_URL" ]; then
    latest="$(curl_with_auth -sI "$MAYA_WORKER_REPO_WEB_URL/releases/latest" 2>/dev/null \
      | grep -i '^location:' \
      | sed 's/.*tag\///' \
      | tr -d '\r\n' || true)"
    if [ -z "$latest" ]; then
      fail "Could not determine latest Maya worker release. Check your network connection."
    fi
    printf '%s' "${latest#v}"
    return
  fi

  latest="$(curl -fsSL "$MAYA_WORKER_DOWNLOAD_BASE_URL/latest.txt" 2>/dev/null \
    | tr -d '\r\n' || true)"
  if [ -z "$latest" ]; then
    fail "Could not determine latest Maya worker release from $MAYA_WORKER_DOWNLOAD_BASE_URL/latest.txt. Check your network connection."
  fi
  printf '%s' "${latest#v}"
}

resolve_archive_url() {
  version="$1"
  archive_name="$2"
  if [ -n "$MAYA_WORKER_REPO_WEB_URL" ]; then
    printf '%s' "$MAYA_WORKER_REPO_WEB_URL/releases/download/v${version}/${archive_name}"
    return
  fi

  printf '%s' "$MAYA_WORKER_DOWNLOAD_BASE_URL/v${version}/${archive_name}"
}

download_archive() {
  url="$1"
  out="$2"
  if [ -n "$MAYA_WORKER_REPO_WEB_URL" ]; then
    curl_with_auth -fsSL "$url" -o "$out"
  else
    curl -fsSL "$url" -o "$out"
  fi
}

install_from_archive() {
  archive_path="$1"
  install_tmp_dir="$(mktemp -d)"

  if tar -xzf "$archive_path" -C "$install_tmp_dir"; then
    if [ -f "$install_tmp_dir/maya" ]; then
      :
    elif [ -f "$install_tmp_dir/maya-worker" ]; then
      cp "$install_tmp_dir/maya-worker" "$install_tmp_dir/maya"
    else
      status=1
      rm -rf "$install_tmp_dir"
      return "$status"
    fi

    # Install maya-worker compatibility alias during the transition from the
    # older worker-named public command to the product-level Maya CLI.
    if [ ! -f "$install_tmp_dir/maya-worker" ]; then
      cp "$install_tmp_dir/maya" "$install_tmp_dir/maya-worker"
    fi

    if mkdir -p "$MAYA_CLI_INSTALL_DIR" \
      && mv "$install_tmp_dir/maya" "$MAYA_CLI_INSTALL_DIR/maya" \
      && mv "$install_tmp_dir/maya-worker" "$MAYA_CLI_INSTALL_DIR/maya-worker" \
      && chmod +x "$MAYA_CLI_INSTALL_DIR/maya" "$MAYA_CLI_INSTALL_DIR/maya-worker"; then
      rm -rf "$install_tmp_dir"
      return 0
    else
      status="$?"
      rm -rf "$install_tmp_dir"
      return "$status"
    fi
  else
    status="$?"
    rm -rf "$install_tmp_dir"
    return "$status"
  fi
}

download_and_install() {
  version="$1"
  archive_name="maya-worker-${version}-${OS}-${ARCH}.tar.gz"
  url="$(resolve_archive_url "$version" "$archive_name")"
  download_tmp_dir="$(mktemp -d)"

  info "Downloading $url"
  if ! download_archive "$url" "$download_tmp_dir/$archive_name"; then
    rm -rf "$download_tmp_dir"
    fail "Failed to download Maya worker release archive."
  fi

  if ! install_from_archive "$download_tmp_dir/$archive_name"; then
    rm -rf "$download_tmp_dir"
    fail "Failed to install Maya worker release archive."
  fi

  rm -rf "$download_tmp_dir"
}

path_contains_dir() {
  case ":$PATH:" in
    *":$1:"*) return 0 ;;
    *) return 1 ;;
  esac
}

install_path_shims() {
  shim_dir="$1"
  [ -n "$shim_dir" ] || return 1
  [ -d "$shim_dir" ] || return 1
  [ -w "$shim_dir" ] || return 1
  path_contains_dir "$shim_dir" || return 1

  # Do not replace unrelated commands. Existing Maya symlinks are safe to
  # refresh when a new release is installed.
  if [ -e "$shim_dir/maya" ] && [ ! -L "$shim_dir/maya" ]; then
    return 1
  fi
  if [ -e "$shim_dir/maya-worker" ] && [ ! -L "$shim_dir/maya-worker" ]; then
    return 1
  fi

  ln -sfn "$MAYA_CLI_INSTALL_DIR/maya" "$shim_dir/maya"
  ln -sfn "$MAYA_CLI_INSTALL_DIR/maya-worker" "$shim_dir/maya-worker"
  ok "maya command linked into $shim_dir"
  return 0
}

# A curl | sh child cannot modify its parent shell environment. Prefer an
# already-on-PATH command shim for immediate use, then fall back to updating
# the user's shell profile for future sessions.
ensure_in_path() {
  if path_contains_dir "$MAYA_CLI_INSTALL_DIR"; then
    return
  fi

  if install_path_shims "$MAYA_CLI_SHIM_DIR"; then
    return
  fi

  if [ "$MAYA_CLI_SHIM_DIR" != "$HOME/.local/bin" ] \
    && install_path_shims "$HOME/.local/bin"; then
    return
  fi

  export PATH="$MAYA_CLI_INSTALL_DIR:$PATH"

  # Determine which shell profile to update.
  profile_file=""
  case "${SHELL:-}" in
    */zsh)
      # Prefer .zshenv (sourced for all zsh invocations) over .zshrc (interactive only).
      for candidate in "$HOME/.zshenv" "$HOME/.zshrc"; do
        if [ -f "$candidate" ]; then
          profile_file="$candidate"
          break
        fi
      done
      # Fall back to .zshenv even if it doesn't exist yet.
      if [ -z "$profile_file" ]; then
        profile_file="$HOME/.zshenv"
      fi
      ;;
    */bash)
      for candidate in "$HOME/.bashrc" "$HOME/.bash_profile"; do
        if [ -f "$candidate" ]; then
          profile_file="$candidate"
          break
        fi
      done
      if [ -z "$profile_file" ]; then
        profile_file="$HOME/.bashrc"
      fi
      ;;
    */sh|*)
      # Generic /bin/sh or unknown — try .profile.
      profile_file="$HOME/.profile"
      ;;
  esac

  # Append the export line if it is not already present in the chosen profile.
  if [ -n "$profile_file" ]; then
    if ! grep -qF "export PATH=\"$MAYA_CLI_INSTALL_DIR:\$PATH\"" "$profile_file" 2>/dev/null; then
      printf '\n# Added by Maya installer\nexport PATH="%s:$PATH"\n' "$MAYA_CLI_INSTALL_DIR" >> "$profile_file"
      ok "PATH updated in $profile_file"
    fi
  fi

  printf '%s\n' ""
  printf '%s\n' "Maya CLI will be available in new shell sessions via $profile_file."
  printf '%s\n' "Run one of the following to use maya right away:"
  printf '%s\n' "  export PATH=\"$MAYA_CLI_INSTALL_DIR:\$PATH\""
  printf '%s\n' "  source \"$profile_file\""
}

print_next_steps() {
  printf '%s\n' ""
  printf '%s\n' "Next:"
  printf '%s\n' "  maya setup"
  printf '%s\n' "  maya status"
}

main() {
  command_exists curl || fail "curl is required to install Maya worker."
  command_exists tar || fail "tar is required to install Maya worker."
  require_node
  detect_os_arch

  if [ -n "$MAYA_WORKER_ARCHIVE_FILE" ]; then
    [ -f "$MAYA_WORKER_ARCHIVE_FILE" ] || fail "MAYA_WORKER_ARCHIVE_FILE does not exist: $MAYA_WORKER_ARCHIVE_FILE"
    info "Installing Maya worker from local archive $MAYA_WORKER_ARCHIVE_FILE"
    if ! install_from_archive "$MAYA_WORKER_ARCHIVE_FILE"; then
      fail "Failed to install Maya worker from local archive."
    fi
    ok "maya installed to $MAYA_CLI_INSTALL_DIR/maya"
    ok "maya-worker compatibility alias installed to $MAYA_CLI_INSTALL_DIR/maya-worker"
    ensure_in_path
    print_next_steps
    return
  fi

  version="$(get_latest_version)"
  info "Installing Maya worker ${version}"
  download_and_install "$version"
  ok "maya installed to $MAYA_CLI_INSTALL_DIR/maya"
  ok "maya-worker compatibility alias installed to $MAYA_CLI_INSTALL_DIR/maya-worker"
  ensure_in_path
  print_next_steps
}

main "$@"
