#!/bin/sh
set -eu
umask 077

fail() { printf '\n%s\n' "$1" >&2; exit 1; }
[ "$(uname -s)" = Darwin ] || fail 'Novix requires macOS 14 or later.'
[ "$(sw_vers -productVersion | cut -d . -f 1)" -ge 14 ] || fail 'Novix requires macOS 14 or later.'
[ "$(id -u)" -ne 0 ] || fail 'Run this as yourself, without sudo.'

destination="$HOME/Applications/Novix.app"
[ ! -L "$HOME/Applications" ] || fail 'Your Applications folder is a symbolic link. Contact support@getnovix.ai.'
verify_app() {
    [ -d "$1" ] && [ ! -L "$1" ] || fail 'Novix.app must be an application, not a symbolic link.'
    codesign --verify --deep --strict --test-requirement '=anchor apple generic and certificate leaf[subject.OU] = "448D2HP264" and identifier "ai.getnovix.collector"' "$1" || fail 'Novix publisher or app signature could not be verified. Nothing was changed. Contact support@getnovix.ai.'
    [ "$(plutil -extract SUPublicEDKey raw -o - "$1/Contents/Info.plist")" = 'zsKDLICuZiPZwMhqfEQOhFglllTUo4jSPzFbLLfiFls=' ] || fail 'Novix update identity could not be verified. Nothing was changed.'
}
open_app() {
    printf 'Allowing this verified preview of Novix to open. Other apps keep their security checks.\n'
    xattr -dr com.apple.quarantine "$1"
    printf 'Opening Novix. Connect your workspace, choose sources, then start syncing.\n'
    open "$1"
}
for existing in /Applications/Novix.app "$destination"; do
    if [ -e "$existing" ] || [ -L "$existing" ]; then
        verify_app "$existing"
        open_app "$existing"
        exit 0
    fi
done

work=$(mktemp -d "${TMPDIR:-/tmp}/novix-install.XXXXXX")
stage=''
mounted=0
cleanup() {
    if [ "$mounted" -eq 1 ]; then hdiutil detach "$work/volume" -quiet || true; fi
    if [ -n "$stage" ]; then rm -rf "$stage"; fi
    rm -rf "$work"
}
trap cleanup EXIT
trap 'exit 1' HUP INT TERM
download() { curl --fail --location --proto '=https' --proto-redir '=https' --connect-timeout 15 --max-time 300 --retry 2 "$1" -o "$2"; }

printf 'Downloading the official Novix installer…\n'
download https://www.getnovix.ai/downloads/collector.json "$work/collector.json"
version=$(plutil -extract version raw -o - "$work/collector.json")
case "$version" in ''|*[!0-9.]*|.*|*..*|*.) fail 'Invalid release version. Nothing was installed.' ;; esac
checksum=$(plutil -extract sha256 raw -o - "$work/collector.json")
[ "${#checksum}" -eq 64 ] || fail 'Invalid release checksum. Nothing was installed.'
case "$checksum" in *[!0-9a-f]*) fail 'Invalid release checksum. Nothing was installed.' ;; esac
download "https://www.getnovix.ai/downloads/Novix-$version.dmg" "$work/Novix.dmg"
printf '%s  %s\n' "$checksum" "$work/Novix.dmg" | shasum -a 256 -c - || fail 'The download did not match the release checksum. Nothing was installed. Please retry.'

mkdir "$work/volume"
hdiutil attach "$work/Novix.dmg" -readonly -nobrowse -mountpoint "$work/volume" -quiet
mounted=1
app="$work/volume/Novix.app"
verify_app "$app"
[ "$(plutil -extract CFBundleShortVersionString raw -o - "$app/Contents/Info.plist")" = "$version" ] || fail 'The app version does not match the release. Nothing was installed.'

mkdir -p "$HOME/Applications"
stage=$(mktemp -d "$HOME/Applications/.novix-install.XXXXXX")
ditto "$app" "$stage/Novix.app"
verify_app "$stage/Novix.app"
[ ! -e "$destination" ] && [ ! -L "$destination" ] || fail 'Another Novix installation appeared. Nothing was replaced.'
mv "$stage/Novix.app" "$destination"
printf 'Installed at %s\n' "$destination"
open_app "$destination"
