#!/usr/bin/env bash
# Root bootstrap script for Aztec toolchain
# This script installs aztec-up and then delegates to it for version installation.
# Usage: bash -i <(curl -s https://install.aztec.network)
#    or: VERSION=0.85.0 bash -i <(curl -s https://install.aztec.network)
set -euo pipefail

# Colors (truecolor with 256-color fallback)
r="\033[0m"  # Reset
bold="\033[1m"
g="\033[38;5;114m"              # green
y="\033[38;5;222m"              # yellow
b="\033[38;5;111m"              # blue
p="\033[38;5;176m"              # purple
red="\033[38;5;203m"            # red

if [ ! -t 0 ]; then
  NON_INTERACTIVE=1
else
  NON_INTERACTIVE=${NON_INTERACTIVE:-0}
fi

# Base paths
AZTEC_HOME="${AZTEC_HOME:-$HOME/.aztec}"
shared_bin_path="$AZTEC_HOME/bin"

VERSION=0.0.1-commit.c0b82b2

# Install URI (root, not version-specific)
INSTALL_URI="${INSTALL_URI:-https://install.aztec-labs.com}"

# Resolve alias (like "nightly") to actual version number.
function resolve_version {
  local version="$1"
  local semver_regex='^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.-]+)?(\+[a-zA-Z0-9.]+)?$'
  if [[ "$version" =~ $semver_regex ]]; then
    echo "$version"
  else
    local resolved
    if ! resolved=$(curl -fsSL "$INSTALL_URI/aliases/$version" 2>/dev/null); then
      echo "Error: Could not resolve alias '$version'" >&2
      exit 1
    fi
    echo "$resolved"
  fi
}

VERSION=0.0.1-commit.c0b82b2

function typewriter {
  local text="$1"
  local color="${2:-}"
  local delay="${3:-0.02}"
  local width=80
  local pad=$(( (width - ${#text}) / 2 ))
  printf "\r\033[2K%${pad}s${color}" ""
  for (( i=0; i<${#text}; i++ )); do printf '%s' "${text:$i:1}"; sleep "$delay"; done
}

function title {
  clear
  if [ "${COLORTERM:-}" = "truecolor" ] || [ "${COLORTERM:-}" = "24bit" ]; then
    curl -fsSL "$INSTALL_URI/$VERSION/aztec-banner-truecolor" 2>/dev/null || true
  else
    curl -fsSL "$INSTALL_URI/$VERSION/aztec-banner" 2>/dev/null || true
  fi
  typewriter "initializing stealth protocols..." "${p}"
  sleep 1
  typewriter "privacy loaded." "${g}"
  sleep 1
  typewriter "surveillance denied." "${red}${bold}"
  sleep 1
  printf "${r}\r"
  echo -e "Welcome to ${bold}${b}Aztec${r}! Your journey into blockchain privacy begins... ${bold}${p}now${r}."
  echo
  echo -e "Installing version: ${bold}${g}$VERSION${r}"
  echo
  echo -e "This script installs the following and updates your PATH if necessary:"
  echo -e "  ${bold}${g}nargo${r}          - the noir programming language compiler and simulator."
  echo -e "  ${bold}${g}noir-profiler${r}  - a profiler for analyzing and visualizing noir programs."
  echo -e "  ${bold}${g}bb${r}             - the barretenberg proving backend."
  echo -e "  ${bold}${g}aztec${r}          - compiles and tests contracts, interacts with the network."
  echo -e "  ${bold}${g}aztec-up${r}       - installs and manages aztec toolchain versions."
  echo -e "  ${bold}${g}aztec-wallet${r}   - a minimalistic wallet cli."
  echo
  read -p "Do you wish to continue? (y/n) " -n 1 -r
  echo
  echo
  if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    exit 1
  fi
}

function check_for_old_install {
  if [ -f "$AZTEC_HOME/bin/.aztec-run" ]; then
    echo_yellow "WARNING: An existing Aztec installation was detected in $AZTEC_HOME."
    echo
    echo "You should only proceed if you no longer intend to use older versions of Aztec installed via the old docker-based method."
    echo -e "Aztec has moved to a native, dockerless installation, using ${bold}${g}aztec-up${r} as a version manager."
    echo "The container is still available but is only useful for running node infrastructure, not contract development."
    echo

    if [ "$NON_INTERACTIVE" -eq 1 ]; then
      echo "Remove $AZTEC_HOME and try again."
      exit 1
    fi

    echo_yellow "If you continue, the entire $AZTEC_HOME directory will be removed and replaced with the new installation."
    echo "You should manually remove old docker images you no longer need."
    echo
    read -p "Do you wish to continue? (y/n) " -n 1 -r
    echo
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
      exit 1
    fi
    rm -rf "$AZTEC_HOME"
  fi
}

function echo_green {
  echo -e "${g}$1${r}"
}

function echo_yellow {
  echo -e "${y}$1${r}"
}

function install_jq {
  url_base="https://github.com/jqlang/jq/releases/download/jq-1.8.1"
  arch="$(uname -m)"
  os="$(uname -s)"

  case "$os" in
    Linux)
      case "$arch" in
        x86_64|amd64) bin="jq-linux-amd64" ;;
        aarch64|arm64) bin="jq-linux-arm64" ;;
        *) echo "unsupported arch"; return 1 ;;
      esac
      ;;
    Darwin)
      case "$arch" in
        x86_64|amd64) bin="jq-macos-amd64" ;;
        aarch64|arm64) bin="jq-macos-arm64" ;;
        *) echo "unsupported arch"; return 1 ;;
      esac
      ;;
    *)
      echo "unsupported OS"
      return 1
      ;;
  esac

  curl -Ls "$url_base/$bin" -o $shared_bin_path/jq || return 1
  chmod +x $shared_bin_path/jq
}

function install_aztec_up {
  # If there's a version of aztec-up at the VERSION location, use that, else fallback to root installer.
  if ! curl -fsSL "$INSTALL_URI/$VERSION/aztec-up" -o "$shared_bin_path/aztec-up"; then
    # Download aztec-up from root.
    curl -fsSL "$INSTALL_URI/aztec-up" -o "$shared_bin_path/aztec-up"
  fi
  chmod +x "$shared_bin_path/aztec-up"
}

# Updates appropriate shell script to ensure the paths are in PATH.
function update_path_env_var {
  # We need both:
  # - $AZTEC_HOME/current/bin and $AZTEC_HOME/current/node_modules/.bin for version-specific tools
  # - $AZTEC_HOME/bin for shared tools like aztec-up
  local path_line="export PATH=\"\$HOME/.aztec/current/bin:\$HOME/.aztec/current/node_modules/.bin:\$HOME/.aztec/bin:\$PATH\""

  # Determine the user's shell.
  local shell_profile=""
  case $SHELL in
  */bash)
    shell_profile="$HOME/.bashrc"
    ;;
  */zsh)
    shell_profile="$HOME/.zshrc"
    ;;
  *)
    echo "Unsupported shell: $SHELL"
    return
    ;;
  esac

  # Check if we already have aztec paths in the profile.
  if grep -q '\.aztec' "$shell_profile" 2>/dev/null; then
    # Remove old aztec PATH entries.
    local tmp_file=$(mktemp)
    grep -Ev 'export PATH=.*/\.aztec/' "$shell_profile" > "$tmp_file" || true
    mv "$tmp_file" "$shell_profile"
  fi

  # Add the path line
  echo "$path_line" >>"$shell_profile"
}

function main {
  # Show title if we're in a terminal.
  [ "$NON_INTERACTIVE" -eq 0 ] && title

  check_for_old_install

  mkdir -p "$shared_bin_path"

  # Install jq
  if ! command -v jq >/dev/null 2>&1; then
    echo -n "Installing jq... "
    install_jq
    echo_green "done."
  fi

  # Install aztec-up (version manager)
  echo -n "Installing aztec-up... "
  install_aztec_up
  echo_green "done."

  # Update PATH
  update_path_env_var

  # Export PATH for this session so aztec-up is available
  export PATH="$shared_bin_path:$PATH"

  # Use aztec-up to install the requested version
  aztec-up install $VERSION

  if [ "$NON_INTERACTIVE" -eq 0 ] && [ "${NO_NEW_SHELL:-0}" -eq 0 ]; then
    echo_green "Done! Starting fresh shell..."
    exec $SHELL
  else
    echo
    echo "Done! You'll need to start a fresh shell to see PATH updates."
    echo
  fi
}

main "$@"
