#!/usr/bin/env bash

set -euo pipefail

BINARY_NAME="smplify"
VERSION="${SMPLIFY_VERSION:-latest}"
INSTALL_DIR="${SMPLIFY_INSTALL_DIR:-}"
RELEASE_BASE_URL="${SMPLIFY_RELEASE_BASE_URL:-https://downloads.smplify.com/releases}"
LATEST_VERSION_URL="${SMPLIFY_RELEASE_LATEST_URL:-${RELEASE_BASE_URL}/latest/version.txt}"
SKIP_CHECKSUM=0

usage() {
  cat <<'EOF'
Install the Smplify CLI from the Smplify release mirror.

Usage:
  install.sh [--version <tag>] [--install-dir <path>] [--skip-checksum]

Options:
  --version <tag>       Install a specific release tag, for example v0.1.0.
  --install-dir <path>  Install into a specific directory.
  --skip-checksum       Skip checksum verification.
  -h, --help            Show this help text.

Environment:
  SMPLIFY_VERSION       Same as --version.
  SMPLIFY_INSTALL_DIR   Same as --install-dir.
  SMPLIFY_RELEASE_BASE_URL
                        Override the release base URL.
  SMPLIFY_RELEASE_LATEST_URL
                        Override the URL used to resolve the latest version.
EOF
}

log() {
  printf '%s\n' "$*"
}

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

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

parse_args() {
  while [ "$#" -gt 0 ]; do
    case "$1" in
      --version)
        [ "$#" -ge 2 ] || fail "--version requires a value"
        VERSION="$2"
        shift 2
        ;;
      --install-dir)
        [ "$#" -ge 2 ] || fail "--install-dir requires a value"
        INSTALL_DIR="$2"
        shift 2
        ;;
      --skip-checksum)
        SKIP_CHECKSUM=1
        shift
        ;;
      -h|--help)
        usage
        exit 0
        ;;
      *)
        fail "Unknown argument: $1"
        ;;
    esac
  done
}

detect_platform() {
  case "$(uname -s)" in
    Darwin) OS="darwin" ;;
    Linux) OS="linux" ;;
    *)
      fail "Unsupported operating system: $(uname -s). Use the release artifacts for manual installation."
      ;;
  esac

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

resolve_version() {
  if [ "$VERSION" != "latest" ]; then
    RESOLVED_VERSION="$VERSION"
    return
  fi

  require_command curl
  if ! RESOLVED_VERSION="$(curl -fsSL "$LATEST_VERSION_URL" 2>/dev/null | tr -d '[:space:]')"; then
    fail "No published Smplify CLI release is available yet at ${LATEST_VERSION_URL}."
  fi
  [ -n "$RESOLVED_VERSION" ] || fail "Failed to resolve the latest Smplify CLI release."
}

select_install_dir() {
  if [ -n "$INSTALL_DIR" ]; then
    mkdir -p "$INSTALL_DIR"
    return
  fi

  if [ -w "/usr/local/bin" ]; then
    INSTALL_DIR="/usr/local/bin"
    return
  fi

  INSTALL_DIR="${HOME}/.local/bin"
  mkdir -p "$INSTALL_DIR"
}

verify_checksum() {
  archive_path="$1"
  checksums_path="$2"
  archive_name="$3"

  expected_line="$(grep " ${archive_name}\$" "$checksums_path" || true)"
  [ -n "$expected_line" ] || fail "Could not find checksum for ${archive_name}"

  if command -v shasum >/dev/null 2>&1; then
    actual="$(shasum -a 256 "$archive_path" | awk '{print $1}')"
  elif command -v sha256sum >/dev/null 2>&1; then
    actual="$(sha256sum "$archive_path" | awk '{print $1}')"
  else
    fail "No SHA256 tool available. Install shasum or sha256sum, or use --skip-checksum."
  fi

  expected="$(printf '%s\n' "$expected_line" | awk '{print $1}')"
  [ "$actual" = "$expected" ] || fail "Checksum verification failed for ${archive_name}"
}

install_binary() {
  archive_name="${BINARY_NAME}_${OS}_${ARCH}.tar.gz"
  download_url="${RELEASE_BASE_URL}/${RESOLVED_VERSION}/${archive_name}"
  checksum_url="${RELEASE_BASE_URL}/${RESOLVED_VERSION}/checksums.txt"

  temp_dir="$(mktemp -d)"
  trap 'rm -rf -- "$temp_dir"' EXIT

  log "Installing ${BINARY_NAME} ${RESOLVED_VERSION} for ${OS}/${ARCH}"
  require_command curl
  require_command tar

  if ! curl -fsSL "$download_url" -o "${temp_dir}/${archive_name}"; then
    fail "Failed to download ${archive_name} from ${download_url}."
  fi
  if [ "$SKIP_CHECKSUM" -eq 0 ]; then
    if ! curl -fsSL "$checksum_url" -o "${temp_dir}/checksums.txt"; then
      fail "Failed to download checksums from ${checksum_url}."
    fi
    verify_checksum "${temp_dir}/${archive_name}" "${temp_dir}/checksums.txt" "${archive_name}"
  fi

  tar -xzf "${temp_dir}/${archive_name}" -C "$temp_dir"
  [ -f "${temp_dir}/${BINARY_NAME}" ] || fail "Archive did not contain ${BINARY_NAME}"

  target_path="${INSTALL_DIR}/${BINARY_NAME}"
  if [ -w "$INSTALL_DIR" ]; then
    install -m 0755 "${temp_dir}/${BINARY_NAME}" "$target_path"
  elif command -v sudo >/dev/null 2>&1; then
    sudo install -m 0755 "${temp_dir}/${BINARY_NAME}" "$target_path"
  else
    fail "Install directory is not writable and sudo is not available: ${INSTALL_DIR}"
  fi

  log ""
  log "Installed ${BINARY_NAME} to ${target_path}"
  case ":${PATH}:" in
    *":${INSTALL_DIR}:"*) ;;
    *)
      log "Add ${INSTALL_DIR} to your PATH if it is not already available."
      ;;
  esac
  log "Run '${BINARY_NAME} auth login' to get started."
}

parse_args "$@"
detect_platform
resolve_version
select_install_dir
install_binary
