#!/usr/bin/env bash
set -euo pipefail

# Internal override hooks used by development and release tooling.
# Public installs should rely on the production defaults below.
DOWNLOAD_BASE_URL="${BIOSIMULANT_CLI_DOWNLOAD_BASE_URL:-https://www.biosimulant.com/cli-releases}"
CHANNEL_OR_VERSION="${1:-stable}"
INSTALL_ROOT="${BIOSIMULANT_CLI_INSTALL_ROOT:-$HOME/.local/share/biosimulant/bin}"
LINK_DIR="${BIOSIMULANT_CLI_LINK_DIR:-$HOME/.local/bin}"
BIN_PATH="$INSTALL_ROOT/biosimulant"
LINK_PATH="$LINK_DIR/biosimulant"
UV_PATH="$INSTALL_ROOT/uv"
TOOLS_ROOT="$HOME/.biosimulant"
TOOLS_PATH="$TOOLS_ROOT/tools"

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "error: required command not found: $1" >&2
    exit 1
  }
}

detect_target() {
  local os arch
  os="$(uname -s)"
  arch="$(uname -m)"
  case "$os" in
    Darwin) os="darwin" ;;
    Linux) os="linux" ;;
    *) echo "error: unsupported OS: $os" >&2; exit 1 ;;
  esac
  case "$arch" in
    arm64|aarch64) arch="arm64" ;;
    x86_64|amd64) arch="x64" ;;
    *) echo "error: unsupported architecture: $arch" >&2; exit 1 ;;
  esac
  printf '%s-%s\n' "$os" "$arch"
}

download_text() {
  curl -fsSL "$1"
}

resolve_version() {
  case "$CHANNEL_OR_VERSION" in
    stable|latest) download_text "$DOWNLOAD_BASE_URL/$CHANNEL_OR_VERSION" | tr -d '[:space:]' ;;
    *) printf '%s\n' "$CHANNEL_OR_VERSION" ;;
  esac
}

json_value_for_target() {
  local manifest="$1"
  local target="$2"
  local key="$3"
  if command -v jq >/dev/null 2>&1; then
    jq -r --arg target "$target" --arg key "$key" '.artifacts[$target][$key] // empty' "$manifest"
    return
  fi
  sed -n "/\"$target\"/,/}/p" "$manifest" \
    | tr ',' '\n' \
    | sed -n "s/.*\"$key\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" \
    | head -n 1
}

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

need_cmd curl
need_cmd tar

TARGET="$(detect_target)"
VERSION="$(resolve_version)"
if [ -z "$VERSION" ]; then
  echo "error: could not resolve Biosimulant CLI version from $CHANNEL_OR_VERSION" >&2
  exit 1
fi

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

MANIFEST_URL="$DOWNLOAD_BASE_URL/$VERSION/manifest.json"
MANIFEST_PATH="$TMP_DIR/manifest.json"
curl -fsSL "$MANIFEST_URL" -o "$MANIFEST_PATH"

EXPECTED_SHA="$(json_value_for_target "$MANIFEST_PATH" "$TARGET" sha256)"
ARTIFACT_URL="$(json_value_for_target "$MANIFEST_PATH" "$TARGET" url)"
ARTIFACT_PATH="$(json_value_for_target "$MANIFEST_PATH" "$TARGET" path)"
UV_SHA="$(json_value_for_target "$MANIFEST_PATH" "$TARGET" uv_sha256)"
UV_URL="$(json_value_for_target "$MANIFEST_PATH" "$TARGET" uv_url)"
UV_ARTIFACT_PATH="$(json_value_for_target "$MANIFEST_PATH" "$TARGET" uv_path)"
TOOLS_SHA="$(json_value_for_target "$MANIFEST_PATH" tools sha256)"
TOOLS_URL="$(json_value_for_target "$MANIFEST_PATH" tools url)"
TOOLS_ARTIFACT_PATH="$(json_value_for_target "$MANIFEST_PATH" tools path)"
if [ -z "$EXPECTED_SHA" ]; then
  echo "error: manifest has no sha256 for $TARGET" >&2
  exit 1
fi
if [ -z "$TOOLS_SHA" ]; then
  echo "error: manifest has no sha256 for CLI tools bundle" >&2
  exit 1
fi
if [ -z "$ARTIFACT_URL" ]; then
  if [ -z "$ARTIFACT_PATH" ]; then
    ARTIFACT_PATH="biosimulant"
  fi
  ARTIFACT_URL="$DOWNLOAD_BASE_URL/$VERSION/$ARTIFACT_PATH"
fi

DOWNLOAD_PATH="$TMP_DIR/biosimulant"
curl -fsSL "$ARTIFACT_URL" -o "$DOWNLOAD_PATH"
ACTUAL_SHA="$(sha256_file "$DOWNLOAD_PATH")"
if [ "$ACTUAL_SHA" != "$EXPECTED_SHA" ]; then
  echo "error: checksum mismatch for $ARTIFACT_URL" >&2
  echo "expected: $EXPECTED_SHA" >&2
  echo "actual:   $ACTUAL_SHA" >&2
  exit 1
fi

mkdir -p "$INSTALL_ROOT" "$LINK_DIR"
install -m 0755 "$DOWNLOAD_PATH" "$BIN_PATH"
if [ -n "$UV_SHA" ]; then
  if [ -z "$UV_URL" ]; then
    if [ -z "$UV_ARTIFACT_PATH" ]; then
      UV_ARTIFACT_PATH="uv"
    fi
    UV_URL="$DOWNLOAD_BASE_URL/$VERSION/$UV_ARTIFACT_PATH"
  fi
  UV_DOWNLOAD_PATH="$TMP_DIR/uv"
  curl -fsSL "$UV_URL" -o "$UV_DOWNLOAD_PATH"
  UV_ACTUAL_SHA="$(sha256_file "$UV_DOWNLOAD_PATH")"
  if [ "$UV_ACTUAL_SHA" != "$UV_SHA" ]; then
    echo "error: checksum mismatch for $UV_URL" >&2
    echo "expected: $UV_SHA" >&2
    echo "actual:   $UV_ACTUAL_SHA" >&2
    exit 1
  fi
  install -m 0755 "$UV_DOWNLOAD_PATH" "$UV_PATH"
fi
if [ -z "$TOOLS_URL" ]; then
  if [ -z "$TOOLS_ARTIFACT_PATH" ]; then
    TOOLS_ARTIFACT_PATH="biosimulant-cli-tools.tar.gz"
  fi
  TOOLS_URL="$DOWNLOAD_BASE_URL/$VERSION/$TOOLS_ARTIFACT_PATH"
fi
TOOLS_DOWNLOAD_PATH="$TMP_DIR/biosimulant-cli-tools.tar.gz"
curl -fsSL "$TOOLS_URL" -o "$TOOLS_DOWNLOAD_PATH"
TOOLS_ACTUAL_SHA="$(sha256_file "$TOOLS_DOWNLOAD_PATH")"
if [ "$TOOLS_ACTUAL_SHA" != "$TOOLS_SHA" ]; then
  echo "error: checksum mismatch for $TOOLS_URL" >&2
  echo "expected: $TOOLS_SHA" >&2
  echo "actual:   $TOOLS_ACTUAL_SHA" >&2
  exit 1
fi
mkdir -p "$TOOLS_ROOT"
tar xzf "$TOOLS_DOWNLOAD_PATH" -C "$TOOLS_ROOT"
if [ ! -f "$TOOLS_PATH/run_preflight_validator.py" ]; then
  echo "error: CLI tools bundle did not install run_preflight_validator.py" >&2
  exit 1
fi
ln -sf "$BIN_PATH" "$LINK_PATH"

echo "Biosimulant CLI $VERSION installed at $BIN_PATH"
if ! printf '%s' ":$PATH:" | grep -q ":$LINK_DIR:"; then
  echo
  echo "Add this to your shell profile so 'biosimulant' is on PATH:"
  echo "  export PATH=\"$LINK_DIR:\$PATH\""
fi
