#!/bin/sh
# SPDX-License-Identifier: Apache-2.0 OR MIT
set -eu

usage() {
  cat <<'EOF'
Usage: install.sh [--verbose]

Environment:
  LAPLACE_INSTALL_BASE_URL  Override release asset base URL.
  LAPLACE_VERSION           Release version or tag. Defaults to latest.
  LAPLACE_CHANNEL           stable, beta, or nightly. Defaults to stable.
  LAPLACE_INSTALL_DIR       Install directory. Defaults to ~/.laplace/bin.
  LAPLACE_VERBOSE           Set to 1, true, or yes for verbose logs.
EOF
}

verbose="${LAPLACE_VERBOSE:-}"
case "$verbose" in
  1|true|TRUE|yes|YES) verbose=1 ;;
  *) verbose=0 ;;
esac

while [ "$#" -gt 0 ]; do
  case "$1" in
    --verbose)
      verbose=1
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "unsupported argument: $1" >&2
      usage >&2
      exit 1
      ;;
  esac
  shift
done

log() {
  if [ "$verbose" = "1" ]; then
    printf '%s\n' "$*" >&2
  fi
}

need_cmd() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "required command not found: $1" >&2
    exit 1
  fi
}

detect_target() {
  os="$(uname -s 2>/dev/null || printf unknown)"
  arch="$(uname -m 2>/dev/null || printf unknown)"

  case "$arch" in
    x86_64|amd64) cpu=x86_64 ;;
    arm64|aarch64) cpu=aarch64 ;;
    *)
      echo "unsupported CPU architecture: $arch" >&2
      exit 1
      ;;
  esac

  case "$os" in
    # Static musl builds run on any Linux distro regardless of glibc version.
    Linux) target="${cpu}-unknown-linux-musl" ;;
    Darwin) target="${cpu}-apple-darwin" ;;
    MINGW*|MSYS*|CYGWIN*) target="${cpu}-pc-windows-msvc" ;;
    *)
      echo "unsupported operating system: $os" >&2
      exit 1
      ;;
  esac

  printf '%s\n' "$target"
}

download() {
  url="$1"
  output="$2"
  log "download $url"
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$url" -o "$output"
  elif command -v wget >/dev/null 2>&1; then
    wget -q "$url" -O "$output"
  else
    echo "curl or wget is required to download Laplace CLI" >&2
    exit 1
  fi
}

sha256_file() {
  file="$1"
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$file" | awk '{print $1}'
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$file" | awk '{print $1}'
  else
    echo "sha256sum or shasum is required to verify Laplace CLI" >&2
    exit 1
  fi
}

tmp_dir="$(mktemp -d "${TMPDIR:-/tmp}/laplace-install.XXXXXX")"
cleanup() {
  rm -rf "$tmp_dir"
}
trap cleanup EXIT HUP INT TERM

target="$(detect_target)"
case "$target" in
  *windows*) ext=zip; bin=laplace.exe ;;
  *) ext=tar.xz; bin=laplace ;;
esac

channel="${LAPLACE_CHANNEL:-stable}"
case "$channel" in
  stable|beta|nightly) ;;
  *)
    echo "unsupported LAPLACE_CHANNEL: $channel" >&2
    exit 1
    ;;
esac

version="${LAPLACE_VERSION:-latest}"
if [ -n "${LAPLACE_INSTALL_BASE_URL:-}" ]; then
  base_url="${LAPLACE_INSTALL_BASE_URL%/}"
elif [ "$version" = "latest" ]; then
  base_url="https://github.com/Laplace-Labs-inc/laplace/releases/latest/download"
else
  case "$version" in
    v*) tag="$version" ;;
    *) tag="v$version" ;;
  esac
  base_url="https://github.com/Laplace-Labs-inc/laplace/releases/download/$tag"
fi

asset="laplace-cli-${target}.${ext}"
archive="$tmp_dir/$asset"
checksum="$tmp_dir/$asset.sha256"

download "$base_url/$asset" "$archive"
download "$base_url/$asset.sha256" "$checksum"

expected="$(awk '{print $1}' "$checksum")"
actual="$(sha256_file "$archive")"
if [ "$expected" != "$actual" ]; then
  echo "SHA256 mismatch for $asset" >&2
  echo "expected: $expected" >&2
  echo "actual:   $actual" >&2
  exit 2
fi

extract_dir="$tmp_dir/extract"
mkdir -p "$extract_dir"
case "$ext" in
  zip)
    need_cmd unzip
    unzip -q "$archive" -d "$extract_dir"
    ;;
  tar.gz)
    tar -xzf "$archive" -C "$extract_dir"
    ;;
  tar.xz)
    tar -xJf "$archive" -C "$extract_dir"
    ;;
esac

binary_path="$(find "$extract_dir" -type f -name "$bin" | head -n 1)"
if [ -z "$binary_path" ]; then
  echo "could not find $bin in $asset" >&2
  exit 1
fi

install_dir="${LAPLACE_INSTALL_DIR:-$HOME/.laplace/bin}"
mkdir -p "$install_dir"
cp "$binary_path" "$install_dir/$bin"
chmod 755 "$install_dir/$bin"

printf 'Laplace CLI installed to %s\n' "$install_dir/$bin"
