#!/usr/bin/env bash
# DeepCode CLI — one-line installer
#
#   curl -fsSL https://deepcode-cli.liksoft.tg/install.sh | bash
#
# Options (env):
#   DEEPCODE_SERVER=https://deepcode.liksoft.tg   Team proxy URL
#   DEEPCODE_VERSION=latest                         release version (e.g. 1.1.0)
#   DEEPCODE_NPM_PACKAGE=@liksoft/deepcode-cli      npm package (when published)
#   DEEPCODE_GITHUB_REPO=LIKSOFT/deepcode           GitHub org/repo (fallback)
#   DEEPCODE_INSTALL_METHOD=auto                    auto | hosted | npm | github
#   DEEPCODE_SKIP_CONFIG=1                          Skip server config step
#   DEEPCODE_SKIP_LOGIN=1                           Skip login hint
#
set -euo pipefail

DEEPCODE_SERVER="${DEEPCODE_SERVER:-https://deepcode.liksoft.tg}"
DEEPCODE_VERSION="${DEEPCODE_VERSION:-latest}"
DEEPCODE_NPM_PACKAGE="${DEEPCODE_NPM_PACKAGE:-@liksoft/deepcode-cli}"
DEEPCODE_GITHUB_REPO="${DEEPCODE_GITHUB_REPO:-LIKSOFT/deepcode}"
DEEPCODE_INSTALL_METHOD="${DEEPCODE_INSTALL_METHOD:-auto}"
DEEPCODE_INSTALL_URL="${DEEPCODE_INSTALL_URL:-https://deepcode-cli.liksoft.tg}"
DEEPCODE_DEFAULT_VERSION="${DEEPCODE_DEFAULT_VERSION:-1.1.0}"

bold() { printf '\033[1m%s\033[0m\n' "$*"; }
info() { printf '  \033[36m▸\033[0m %s\n' "$*"; }
warn() { printf '  \033[33m!\033[0m %s\n' "$*"; }
die()  { printf '  \033[31m✗\033[0m %s\n' "$*" >&2; exit 1; }

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || die "Missing required command: $1"
}

node_major() {
  node -p "parseInt(process.versions.node.split('.')[0], 10)" 2>/dev/null || echo 0
}

resolve_cli_version() {
  local version="${DEEPCODE_VERSION}"
  if [ "$version" != "latest" ]; then
    echo "${version#v}"
    return 0
  fi
  local from_manifest
  from_manifest="$(curl -fsSL "${DEEPCODE_INSTALL_URL}/releases/latest.txt" 2>/dev/null | tr -d '[:space:]' || true)"
  if [ -n "$from_manifest" ]; then
    echo "${from_manifest#v}"
    return 0
  fi
  echo "${DEEPCODE_DEFAULT_VERSION#v}"
}

npm_install_global() {
  local spec="$1"
  local use_force=0
  # Overwrite existing global binary (e.g. old deepcode v1.0.0 from npm link / hermes)
  if command -v deepcode >/dev/null 2>&1 || npm list -g --depth=0 2>/dev/null | grep -q 'deepcode'; then
    use_force=1
    info "Upgrading existing deepcode install…"
  fi
  _npm_global() {
    if [ "$use_force" -eq 1 ]; then
      npm install -g --force "$spec"
    else
      npm install -g "$spec"
    fi
  }
  if [ "$(id -u)" -eq 0 ]; then
    _npm_global
  else
    _npm_global 2>/dev/null || {
      warn "Global npm install failed — retrying with sudo…"
      if [ "$use_force" -eq 1 ]; then
        sudo npm install -g --force "$spec"
      else
        sudo npm install -g "$spec"
      fi
    }
  fi
}

install_via_hosted_release() {
  need_cmd curl
  need_cmd npm
  local version asset url tmp
  version="$(resolve_cli_version)"
  asset="deepcode-cli-${version}.tgz"
  url="${DEEPCODE_INSTALL_URL}/releases/${asset}"
  tmp="$(mktemp -d)"
  trap 'rm -rf "$tmp"' RETURN
  info "Downloading ${url}…"
  curl -fsSL "$url" -o "${tmp}/${asset}"
  npm_install_global "${tmp}/${asset}"
}

install_via_npm() {
  need_cmd npm
  local spec="${DEEPCODE_NPM_PACKAGE}"
  if [ -n "$DEEPCODE_VERSION" ] && [ "$DEEPCODE_VERSION" != "latest" ]; then
    spec="${spec}@${DEEPCODE_VERSION}"
  fi
  info "Installing ${spec} via npm registry…"
  npm_install_global "$spec"
}

install_via_github_release() {
  need_cmd curl
  need_cmd npm
  local version asset url tmp gh_version
  version="$(resolve_cli_version)"
  asset="deepcode-cli-${version}.tgz"
  url="${DEEPCODE_INSTALL_URL}/releases/${asset}"
  if ! curl -fsI "$url" >/dev/null 2>&1; then
    gh_version="v${version}"
    url="https://github.com/${DEEPCODE_GITHUB_REPO}/releases/download/${gh_version}/${asset}"
  fi
  tmp="$(mktemp -d)"
  trap 'rm -rf "$tmp"' RETURN
  info "Downloading ${url}…"
  curl -fsSL "$url" -o "${tmp}/${asset}"
  npm_install_global "${tmp}/${asset}"
}

install_via_github_source() {
  need_cmd curl
  need_cmd tar
  need_cmd npm
  local branch="${DEEPCODE_GITHUB_BRANCH:-main}"
  local tmp
  tmp="$(mktemp -d)"
  trap 'rm -rf "$tmp"' RETURN
  info "Building CLI from GitHub source (${DEEPCODE_GITHUB_REPO}@${branch})…"
  curl -fsSL "https://codeload.github.com/${DEEPCODE_GITHUB_REPO}/tar.gz/${branch}" \
    | tar xz -C "$tmp" --strip-components=1
  cd "$tmp/packages/cli"
  npm install --omit=dev --no-audit --no-fund
  npm run build
  npm_install_global "."
}

fix_deepcode_config_permissions() {
  local dir="${HOME}/.deepcode"
  [ -d "$dir" ] || return 0
  local user="${SUDO_USER:-$(whoami)}"
  if [ "$(id -u)" -eq 0 ] && [ -n "${SUDO_USER:-}" ]; then
    chown -R "$user" "$dir" 2>/dev/null || true
  fi
  chmod 700 "$dir" 2>/dev/null || true
  if [ -f "$dir/deepcode-settings.json" ]; then
    chmod 600 "$dir/deepcode-settings.json" 2>/dev/null || true
  fi
}

configure_server() {
  [ "${DEEPCODE_SKIP_CONFIG:-0}" = "1" ] && return 0
  command -v deepcode >/dev/null 2>&1 || return 0
  info "Configuring DeepCode Server → ${DEEPCODE_SERVER}"
  if [ "$(id -u)" -eq 0 ] && [ -n "${SUDO_USER:-}" ]; then
    sudo -u "$SUDO_USER" -H deepcode config --enable-server --server-url "$DEEPCODE_SERVER" >/dev/null 2>&1 || \
      warn "Could not auto-configure server (run: deepcode config --enable-server --server-url ${DEEPCODE_SERVER})"
    return 0
  fi
  deepcode config --enable-server --server-url "$DEEPCODE_SERVER" >/dev/null 2>&1 || \
    warn "Could not auto-configure server (run: deepcode config --enable-server --server-url ${DEEPCODE_SERVER})"
}

try_install() {
  local fn="$1"
  local err
  err="$(mktemp)"
  if ( set -e; "$fn" ) 2>"$err"; then
    rm -f "$err"
    return 0
  fi
  if [ -s "$err" ]; then
    warn "Install step failed: $(tail -n 3 "$err" | tr '\n' ' ')"
  fi
  rm -f "$err"
  return 1
}

main() {
  bold "DeepCode CLI installer"
  echo

  if [ "$(id -u)" -eq 0 ] && [ -z "${DEEPCODE_ALLOW_ROOT:-}" ]; then
    warn "Running as root can break ~/.deepcode permissions."
    warn "Prefer: curl -fsSL ${DEEPCODE_INSTALL_URL}/install.sh | bash   (without sudo)"
  fi

  if ! command -v node >/dev/null 2>&1; then
    die "Node.js 18+ is required. Install from https://nodejs.org then re-run this script."
  fi
  local major
  major="$(node_major)"
  [ "$major" -ge 18 ] || die "Node.js 18+ required (found v$(node -v))"

  if command -v deepcode >/dev/null 2>&1; then
    warn "deepcode is already installed: $(deepcode --version 2>/dev/null || echo 'unknown')"
  fi

  case "$DEEPCODE_INSTALL_METHOD" in
    hosted)  try_install install_via_hosted_release || die "Hosted install failed" ;;
    npm)     try_install install_via_npm || die "npm install failed" ;;
    github)  try_install install_via_github_release || try_install install_via_github_source || die "GitHub install failed" ;;
    auto|*)
      if try_install install_via_hosted_release; then
        :
      elif try_install install_via_npm; then
        :
      else
        die "Install failed. Hosted tarball: ${DEEPCODE_INSTALL_URL}/releases/deepcode-cli-$(resolve_cli_version).tgz — check npm permissions or run: npm install -g --force <tarball>"
      fi
      ;;
  esac

  command -v deepcode >/dev/null 2>&1 || die "Installation failed — deepcode not found in PATH"

  configure_server
  fix_deepcode_config_permissions

  echo
  bold "Installed successfully"
  info "$(deepcode --version 2>/dev/null || echo deepcode)"
  info "Server:  ${DEEPCODE_SERVER}"
  if [ "${DEEPCODE_SKIP_LOGIN:-0}" != "1" ]; then
    echo
    info "Sign in (device code):  deepcode login"
    info "Or with custom proxy:   deepcode login --server-url ${DEEPCODE_SERVER}"
    info "Docs:                   ${DEEPCODE_INSTALL_URL}"
  fi
  echo
}

main "$@"