#!/bin/bash

set -euo pipefail
shopt -s nullglob

detect_target_device() {
    # Pick the first non-removable, non-virtual block device. Prefer NVMe
    # (the 410b/520 default), fall back to SATA/SCSI on older appliances.
    local usb_wic_installer_disk
    usb_wic_installer_disk="$(detect_usb_wic_installer_disk || true)"

    local d
    for d in /sys/block/nvme*n* /sys/block/sd*; do
        d="${d##*/}"

        # Only install to whole block devices that exist under /dev.
        # Partitions, missing device nodes, and stale sysfs entries are not
        # valid targets for writing a full disk image.
        [ -b "/dev/$d" ] || continue

        # Real hardware disks have a backing device in sysfs. Virtual block
        # devices such as loop, dm, and zram must never be auto-selected for
        # the destructive installer write.
        [ -e "/sys/block/$d/device" ] || continue

        # Removable media is usually the installer USB stick. It is not a
        # reliable target for Edge OS, and overwriting it can kill the running
        # installer before the appliance disk has been installed.
        [ "$(cat "/sys/block/$d/removable" 2>/dev/null)" = "0" ] || continue

        # Some USB media reports itself as non-removable. When booting the
        # installer.wic image, skip the disk that contains its installroot
        # partition even if the kernel exposes it as /dev/sdX.
        [ "$d" != "$usb_wic_installer_disk" ] || continue

        echo "/dev/$d"
        return 0
    done
    return 1
}

detect_usb_wic_installer_disk() {
    # Only the bootable installer.wic image uses root=PARTLABEL=installroot.
    # In-place installer flows run from an initramfs and must still be allowed
    # to overwrite the disk they were staged on.
    local root
    local part
    local dev

    root="$(awk 'BEGIN { RS=" "; FS="=" } $1 == "root" { print $2; exit }' < /proc/cmdline)"
    [ "$root" = "PARTLABEL=installroot" ] || return 1

    part="$(readlink -f /dev/disk/by-partlabel/installroot 2>/dev/null)"

    dev="${part##*/}"
    [ -e "/sys/class/block/$dev/partition" ] || return 1
    basename "$(dirname "$(readlink -f "/sys/class/block/$dev")")"
}

verify_connectivity() {
    local url="$1"

    echo >&2 "Verifying internet connectivity to $url"

    for attempt in {1..100}; do
        if wget --spider -T 2 "$url" 2>/dev/null; then
            echo >&2 "Internet connectivity verified"
            return 0
        fi

        echo >&2 "[$attempt/100] Connectivity check failed"

        sleep 2
    done

    echo >&2 "Error: No internet connectivity"
    echo >&2 "Please check network configuration and internet access"
    return 1
}

# Use provided device or auto-detect the appliance's internal disk.
if [ $# -eq 1 ]; then
    device="$1"
    echo >&2 "Using specified installation target: $device"
else
    device=$(detect_target_device || true)
    if [ -z "$device" ]; then
        echo >&2 "Error: No internal disk found for auto-detection"
        echo >&2 "Usage: $0 [device]"
        echo >&2 "  device: target block device (auto-detected if not specified)"
        exit 1
    fi
    echo >&2 "Auto-detected installation target: $device"
fi

# Verify device exists and is a block device
if [ ! -b "$device" ]; then
    echo >&2 "Error: $device is not a valid block device"
    exit 1
fi

# Resolve install target. Two callers:
#   1. PXE installer       — params come from the kernel cmdline
#                            (edgeos.image, edgeos.version, edgeos.env).
#   2. Installer RAUC bundle — the bundle's cpio bakes /etc/edge-installer.conf
#                            with EDGE_INSTALLER_IMAGE / _VERSION; env is
#                            derived from the version pattern below.
image=""
version=""
env=""

if [ -f /etc/edge-installer.conf ]; then
    # shellcheck disable=SC1091
    . /etc/edge-installer.conf
    image="${EDGE_INSTALLER_IMAGE:-}"
    version="${EDGE_INSTALLER_VERSION:-}"
fi

# Fall back to /proc/cmdline (PXE flow). Each lookup only runs if the conf
# file didn't supply that field, so a partial conf still works.
[ -n "$version" ] || version=$(awk 'BEGIN { RS=" "; FS="=" } /edgeos.version/ { print $2 }' < /proc/cmdline)
[ -n "$env" ]     || env=$(awk 'BEGIN { RS=" "; FS="=" } /edgeos.env/ { print $2 }' < /proc/cmdline)
[ -n "$image" ]   || image=$(awk 'BEGIN { RS=" "; FS="=" } /edgeos.image/ { print $2 }' < /proc/cmdline)

# Bundle path doesn't bake env (cmdline always wins for PXE). If we got here
# without one, derive from the version pattern: Rx.x.x lives on
# artifacts.nimbra.io, ci-XXXXXXXXXX lives on artifacts.nimbra.dev.
if [ -z "$env" ]; then
    case "$version" in
        R*) env="prod" ;;
        *)  env="dev" ;;
    esac
fi

if [ -z "$version" ]; then
    echo "Warning: edgeos.version not found in kernel cmdline, using 'latest'"
    version="latest"
fi

if [ -z "$image" ]; then
    echo "Warning: edgeos.image not found in kernel cmdline, defaulting to 'edge-connect'"
    image="edge-connect"
fi

echo >&2 "Installing edgeos image: $image version: $version from $env"

# Construct versioned URL
if [ "$env" == "dev" ]; then
    artifacts=artifacts.nimbra.dev
    url="https://$artifacts/api/artifacts/edgeos/v1/${image}-image-dev/$version/${image}-image-dev-nimbra.rootfs.wic.zst"
else
    artifacts=artifacts.nimbra.io
    url="https://$artifacts/api/artifacts/edgeos/v1/${image}-image/$version/${image}-image-nimbra.rootfs.wic.zst"
fi

echo >&2 "Will download $url"

# Verify connectivity before attempting download
if ! verify_connectivity "https://$artifacts"; then
    exit 1
fi

wget "$url" --spider # Check if the file exists - uses HEAD
wget "$url" -O - | unzstd | dd of="${device}"

echo >&2 "Fixing partition table"
parted --script --fix "${device}"

echo >&2 "Configuring UEFI boot variable"
efibootmgr --delete-bootnum --label "Edge OS" || true
# This should set the boot order but does not seem to work, at least on a 414b
efibootmgr --create --disk "${device}" --part 1 --loader "\EFI\BOOT\BOOTX64.EFI" --label "Edge OS"
# setting bootnext does however
bootnum=$(efibootmgr | awk '/Edge OS/ { print substr($1, 5, 4) }')
efibootmgr --bootnext "$bootnum"
echo >&2 "installation done"
