#!/bin/sh
#
# NeuraCore installer for the Raspberry Pi.
#
#   curl -fsSL https://download.neuracore.ch/install-raspberry.sh | sudo sh
#
# This adds the NeuraCore package repository for 64-bit ARM and its signing
# key, then installs NeuraCore from it as an ordinary package. Afterwards
# `sudo apt update && sudo apt upgrade` keeps it current along with the rest of
# the system, and nothing here ever replaces a file behind apt's back.
#
# It is generated by NeuraCoreDeploy and carries this release's signing
# fingerprint. Read it before running it; that is what the pipe into `sh`
# deserves.

set -eu

SITE="https://download.neuracore.ch"
KEY_FINGERPRINT="85D8D6B36EE7AD08922E94405401ED04C8BE02A8"

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

# Root is needed to install software, and asking for it up front is better than
# failing halfway through with a permission error.
[ "$(id -u)" = "0" ] || fail "Please run this with sudo:  curl -fsSL $SITE/install-raspberry.sh | sudo sh"

command -v apt-get >/dev/null 2>&1 || fail "This does not look like Raspberry Pi OS or any other Debian system: apt-get is not here. See $SITE for the other ways to install NeuraCore."
command -v curl >/dev/null 2>&1 || fail "curl is required to fetch the signing key:  sudo apt install curl"

# What the firmware calls this board. Present on every Raspberry Pi and absent
# on an ordinary PC, so it is reported when it is there and skipped when it is
# not, rather than being required.
if [ -r /proc/device-tree/model ]; then
    MODEL=$(tr -d '\0' < /proc/device-tree/model)
    say "Installing NeuraCore on: $MODEL"
fi

# The architecture, which is what decides whether there is a package at all.
# A 32-bit Raspberry Pi OS is the common case worth answering properly: it is
# the default download on the Raspberry Pi site for older boards, it runs
# perfectly well, and NeuraCore is not published for it. apt on its own would
# say only that there is no installation candidate.
DPKG_ARCH=$(dpkg --print-architecture 2>/dev/null || echo unknown)
case "$DPKG_ARCH" in
    arm64)
        ;;
    armhf|armel)
        fail "This Raspberry Pi is running the 32-bit ($DPKG_ARCH) Raspberry Pi OS, and NeuraCore is published only for the 64-bit one. Check with: uname -m . A Pi 3, 4, 5, 400, 500 or Zero 2 W can run the 64-bit system; reinstall it with Raspberry Pi Imager, choosing the 64-bit edition, and run this again."
        ;;
    amd64)
        fail "This is a 64-bit x86 machine rather than a Raspberry Pi, so it wants the ordinary installer:  curl -fsSL $SITE/install.sh | sudo sh"
        ;;
    *)
        fail "This machine reports the $DPKG_ARCH architecture, and NeuraCore is published for arm64 and amd64 only. See $SITE."
        ;;
esac

say "Adding the NeuraCore repository for 64-bit ARM ..."
mkdir -p /etc/apt/keyrings
# The armoured key is used directly. apt has read `signed-by` keyrings in this
# form since 2.4, which is every Raspberry Pi OS from Bookworm on, and it keeps
# the key out of the deprecated system-wide trusted set where it would have
# been trusted for every repository on the machine rather than only this one.
curl -fsSL "$SITE/neuracore.asc" -o /etc/apt/keyrings/neuracore.asc
chmod 0644 /etc/apt/keyrings/neuracore.asc

# Its own repository root, not the x86 one. An apt suite's Release file names
# the architectures it serves, so the two releases are served from two roots
# and a publication of either cannot disturb the other.
printf '%s\n' \
    "deb [arch=arm64 signed-by=/etc/apt/keyrings/neuracore.asc] $SITE/apt-arm64 stable main" \
    > /etc/apt/sources.list.d/neuracore.list

apt-get update
apt-get install -y neuracore

say ""
say "NeuraCore is installed. Start it from your applications menu, or run: neuracore"
say "It will upgrade with the rest of your system from now on."
say "The signing key this repository is verified against is $KEY_FINGERPRINT."
