#!/usr/bin/env bash
#
# Install m-code.
#
#   curl -fsSL https://m.code.theafricablockchaincenter.com/install.sh | sh
#
# What this script will not do is the point of it: it will not install a binary
# it has not verified. The download comes over a network from a host neither you
# nor this script controls at the moment it runs, so the checksum file is
# fetched alongside the binary and the hash is checked before anything is moved
# into place. A mismatch aborts and says so in as many words.
#
# Everything happens in a temporary directory removed on exit, including on
# failure, so a half-finished install leaves nothing behind.
#
# Overridable, mostly for testing a staging host:
#   M_ORIGIN    where to download from      (default: the URL above)
#   M_VERSION   which release               (default: latest)
#   M_BIN_DIR   where to install            (default: ~/.local/bin)
set -euo pipefail

ORIGIN="${M_ORIGIN:-https://m.code.theafricablockchaincenter.com}"
VERSION="${M_VERSION:-latest}"
BIN_DIR="${M_BIN_DIR:-$HOME/.local/bin}"

say() { printf '%s\n' "$*"; }
die() { printf 'error: %s\n' "$*" >&2; exit 1; }

need() { command -v "$1" >/dev/null 2>&1 || die "$1 is required"; }
need curl
need uname
need mktemp

# --- which binary -------------------------------------------------------------

os="$(uname -s)"
arch="$(uname -m)"

case "$os" in
  Darwin) os_name=darwin ;;
  Linux)  os_name=linux ;;
  *) die "unsupported operating system: $os
On Windows, install inside WSL 2 and run this again there." ;;
esac

case "$arch" in
  arm64|aarch64) arch_name=arm64 ;;
  x86_64|amd64)  arch_name=x64 ;;
  *) die "unsupported architecture: $arch (build from source instead)" ;;
esac

asset="m-code-${os_name}-${arch_name}"
base="${ORIGIN}/releases/${VERSION}"

# --- download and verify ------------------------------------------------------

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

say "downloading ${asset}"
curl -fsSL --retry 3 --retry-delay 2 "${base}/${asset}" -o "${tmp}/${asset}" \
  || die "could not download ${asset} from ${base}"
curl -fsSL --retry 3 "${base}/SHA256SUMS" -o "${tmp}/SHA256SUMS" \
  || die "no SHA256SUMS at ${base} — refusing to install an unverified binary"

expected="$(grep " ${asset}\$" "${tmp}/SHA256SUMS" | awk '{print $1}' || true)"
[ -n "$expected" ] || die "${asset} is not listed in SHA256SUMS"

if command -v sha256sum >/dev/null 2>&1; then
  actual="$(sha256sum "${tmp}/${asset}" | awk '{print $1}')"
elif command -v shasum >/dev/null 2>&1; then
  actual="$(shasum -a 256 "${tmp}/${asset}" | awk '{print $1}')"
else
  die "neither sha256sum nor shasum is available; cannot verify the download"
fi

if [ "$expected" != "$actual" ]; then
  die "checksum mismatch for ${asset}
  expected ${expected}
  actual   ${actual}
This is not a network hiccup. Do not install it."
fi
say "checksum ok"

# --- install ------------------------------------------------------------------

mkdir -p "$BIN_DIR"
chmod +x "${tmp}/${asset}"
mv "${tmp}/${asset}" "${BIN_DIR}/m-code"

say "installed ${BIN_DIR}/m-code"
"${BIN_DIR}/m-code" --version >/dev/null 2>&1 || die "the installed binary does not run"

on_path=no
case ":${PATH}:" in *":${BIN_DIR}:"*) on_path=yes ;; esac

say ""
if [ "$on_path" = no ]; then
  say "${BIN_DIR} is not on your PATH. Add this to your shell profile:"
  say ""
  say "    export PATH=\"${BIN_DIR}:\$PATH\""
  say ""
fi

say "next:"
say "  1. ask for an m-code key, then:  m-code activate <key>"
say "  2. give it a model — a key for any provider, or a local one:"
say "       echo 'export DEEPSEEK_API_KEY=...' >> ~/.config/m-code/env"
say "  3. cd into a project and run:    m-code"
say ""
say "the guide: ${ORIGIN}"
