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

REPO="${BIOMCP_GITHUB_REPO:-genomoncology/biomcp}"
INSTALL_DIR="${BIOMCP_INSTALL_DIR:-$HOME/.local/bin}"
VERSION="${BIOMCP_VERSION:-latest}"

usage() {
  cat <<'EOF'
Usage: install.sh [--version <tag>] [--help]

Options:
  -V, --version  Install a specific release version (e.g., 0.4.1 or v0.4.1)
  -h, --help     Show this help text
EOF
}

download() {
  local url="$1"
  local dest="$2"

  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$url" -o "$dest"
  elif command -v wget >/dev/null 2>&1; then
    wget -qO "$dest" "$url"
  else
    echo "curl or wget is required to download biomcp" >&2
    return 1
  fi
}

download_optional_checksum() {
  local url="$1"
  local dest="$2"
  local status=""

  if command -v curl >/dev/null 2>&1; then
    status="$(curl -sSL -o "$dest" -w '%{http_code}' "$url")" || return 1
  elif command -v wget >/dev/null 2>&1; then
    # Wget writes HTTP status lines to stderr; use the final status after redirects.
    local headers
    headers="$(wget -qS -O "$dest" "$url" 2>&1 || true)"
    status="$(printf '%s\n' "$headers" | awk '/^  HTTP\// { code=$2 } END { print code }')"
  else
    echo "curl or wget is required to download biomcp" >&2
    return 1
  fi

  if [[ "$status" == "200" ]]; then
    return 0
  fi

  rm -f "$dest"
  if [[ "$status" == "404" ]]; then
    return 2
  fi

  if [[ -n "$status" ]]; then
    echo "Failed to download checksum file (HTTP $status): $url" >&2
  else
    echo "Failed to download checksum file: $url" >&2
  fi
  return 1
}

compute_sha256() {
  local file="$1"
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$file" | awk '{print tolower($1)}'
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$file" | awk '{print tolower($1)}'
  else
    return 1
  fi
}

verify_checksum() {
  local archive="$1"
  local checksum_file="$2"
  local expected
  local actual

  expected="$(awk 'NF {print tolower($1); exit}' "$checksum_file" | tr -d '\r')"
  if [[ ! "$expected" =~ ^[0-9a-f]{64}$ ]]; then
    echo "Checksum file is invalid: $checksum_file" >&2
    return 1
  fi

  if ! actual="$(compute_sha256 "$archive")"; then
    echo "Warning: no SHA256 tool available; skipping checksum verification." >&2
    return 0
  fi

  if [[ "$actual" != "$expected" ]]; then
    echo "Checksum verification failed for $(basename "$archive")" >&2
    echo "Expected: $expected" >&2
    echo "Actual:   $actual" >&2
    return 1
  fi

  echo "Checksum verified."
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    -V|--version)
      if [[ $# -lt 2 ]]; then
        echo "--version requires a value" >&2
        usage >&2
        exit 1
      fi
      VERSION="$2"
      shift 2
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Unknown argument: $1" >&2
      usage >&2
      exit 1
      ;;
  esac
done

OS="$(uname -s)"
ARCH="$(uname -m)"

case "$OS" in
  Linux) OS_ID="linux" ;;
  Darwin) OS_ID="darwin" ;;
  MINGW*|MSYS*|CYGWIN*) OS_ID="windows" ;;
  *)
    echo "Unsupported OS: $OS" >&2
    exit 1
    ;;
esac

case "$ARCH" in
  x86_64|amd64) ARCH_ID="x86_64" ;;
  arm64|aarch64) ARCH_ID="arm64" ;;
  *)
    echo "Unsupported architecture: $ARCH" >&2
    exit 1
    ;;
esac

ASSET=""
case "$OS_ID/$ARCH_ID" in
  linux/x86_64) ASSET="biomcp-linux-x86_64.tar.gz" ;;
  linux/arm64) ASSET="biomcp-linux-arm64.tar.gz" ;;
  darwin/x86_64) ASSET="biomcp-darwin-x86_64.tar.gz" ;;
  darwin/arm64) ASSET="biomcp-darwin-arm64.tar.gz" ;;
  windows/x86_64) ASSET="biomcp-windows-x86_64.zip" ;;
  *)
    echo "Unsupported platform: $OS_ID $ARCH_ID" >&2
    exit 1
    ;;
esac

if [[ "$VERSION" == "latest" ]]; then
  # Resolve to the most recent release that has our platform binary.
  # A newly-created release may not have assets yet (builds take minutes),
  # so we skip releases without the required asset file.
  RESOLVED_TAG=""
  api_url="https://api.github.com/repos/${REPO}/releases"
  if command -v jq >/dev/null 2>&1 && releases_json="$(curl -fsSL "$api_url" 2>/dev/null)"; then
    RESOLVED_TAG="$(printf '%s' "$releases_json" | \
      jq -r --arg asset "$ASSET" \
        '[.[] | select(.draft==false and .prerelease==false) | select(.assets[]?.name == $asset)][0].tag_name // empty' 2>/dev/null)" || true
  fi
  if [[ -z "$RESOLVED_TAG" ]]; then
    # API unavailable or no release with assets — fall back to GitHub redirect
    DOWNLOAD_URL="https://github.com/${REPO}/releases/latest/download/${ASSET}"
  else
    echo "Resolved latest release with assets: ${RESOLVED_TAG}"
    DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${RESOLVED_TAG}/${ASSET}"
  fi
else
  TAG="${VERSION#v}"
  DOWNLOAD_URL="https://github.com/${REPO}/releases/download/v${TAG}/${ASSET}"
fi

tmpdir="$(mktemp -d)"
cleanup() { rm -rf "$tmpdir"; }
trap cleanup EXIT

mkdir -p "$INSTALL_DIR"

echo "Downloading ${ASSET} from ${REPO} (version: ${VERSION})..."

archive_path="$tmpdir/$ASSET"
download "$DOWNLOAD_URL" "$archive_path"

checksum_path="$archive_path.sha256"
if download_optional_checksum "${DOWNLOAD_URL}.sha256" "$checksum_path"; then
  echo "Verifying checksum..."
  verify_checksum "$archive_path" "$checksum_path"
else
  checksum_status=$?
  if [[ $checksum_status -eq 2 ]]; then
    echo "Warning: checksum file not found for this release; continuing without checksum verification." >&2
  else
    echo "Checksum download failed; aborting installation." >&2
    exit 1
  fi
fi

bin_path=""
if [[ "$ASSET" == *.tar.gz ]]; then
  tar -xzf "$archive_path" -C "$tmpdir"
  if [[ -f "$tmpdir/biomcp" ]]; then
    bin_path="$tmpdir/biomcp"
  elif [[ -f "$tmpdir/bin/biomcp" ]]; then
    bin_path="$tmpdir/bin/biomcp"
  else
    echo "Could not find biomcp binary in archive" >&2
    exit 1
  fi
elif [[ "$ASSET" == *.zip ]]; then
  if ! command -v unzip >/dev/null 2>&1; then
    echo "unzip is required to install on Windows shells" >&2
    exit 1
  fi
  unzip -q "$archive_path" -d "$tmpdir"
  if [[ -f "$tmpdir/biomcp.exe" ]]; then
    bin_path="$tmpdir/biomcp.exe"
  else
    echo "Could not find biomcp.exe in archive" >&2
    exit 1
  fi
else
  echo "Unsupported archive format: $ASSET" >&2
  exit 1
fi

chmod +x "$bin_path" || true
installed_bin="$INSTALL_DIR/$(basename "$bin_path")"
mv -f "$bin_path" "$installed_bin"

echo "Installed biomcp to $installed_bin"

if ! installed_version="$("$installed_bin" version 2>/dev/null | head -n 1)"; then
  echo "Install verification failed: $installed_bin version" >&2
  exit 1
fi
if [[ -n "$installed_version" ]]; then
  echo "Verified installation: $installed_version"
else
  echo "Verified installation: biomcp version returned successfully"
fi

if [[ "$INSTALL_DIR" == "$HOME/.local/bin" ]]; then
  if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
    shell_name="$(basename "${SHELL:-}")"
    if [[ "$shell_name" == "zsh" ]]; then
      rc="$HOME/.zshrc"
      line='export PATH="$HOME/.local/bin:$PATH"'
      grep -Fqs "$line" "$rc" 2>/dev/null || printf "\n%s\n" "$line" >> "$rc"
      echo "Updated PATH in $rc"
    elif [[ "$shell_name" == "bash" ]]; then
      rc="$HOME/.bashrc"
      line='export PATH="$HOME/.local/bin:$PATH"'
      grep -Fqs "$line" "$rc" 2>/dev/null || printf "\n%s\n" "$line" >> "$rc"
      echo "Updated PATH in $rc"
    elif [[ "$shell_name" == "fish" ]]; then
      rc="$HOME/.config/fish/config.fish"
      mkdir -p "$(dirname "$rc")"
      line='set -gx PATH $HOME/.local/bin $PATH'
      grep -Fqs "$line" "$rc" 2>/dev/null || printf "\n%s\n" "$line" >> "$rc"
      echo "Updated PATH in $rc"
    else
      printf 'Add to PATH:\n  export PATH="$HOME/.local/bin:$PATH"\n' >&2
    fi
  fi
else
  echo "Ensure $INSTALL_DIR is on your PATH"
fi

printf "Verify:\\n  biomcp version\\n"
