#!/usr/bin/env bash

exec | tee bootp.log

set -ex

_fail() {
    echo "$@" >&2
    ip addr
    exit 1
}

# The Arch image 'helpfully' does a bunch of stuff.
# Which isn't coordinated with this script.
# Sigh.
# So coordinate.
systemctl start etc-pacman.d-gnupg.mount
systemctl start pacman-init.service
systemctl start reflector.service

# Configure the root SSH key etc.
curl "https://pxe.tirefireind.us/scripts/root.sh" | bash

# This is 'archiso' at this point - we want to reset it as needed
unset HOSTNAME

EXTRAPKGS=()

# Use the disk sizes and cpuinfo as a fingerprint
if [ -e "/dev/sda" ] && [ 128035676160 -eq $(blockdev --getsize64 /dev/sda) ] && \
     [ "FAB1" == "$(cat /sys/class/dmi/id/board_version)" ] && \
     [ "SAMSUNG ELECTRONICS CO., LTD." == "$(cat /sys/class/dmi/id/board_vendor)" ] && \
     [ "SAMSUNG_NP1234567890" == "$(cat /sys/class/dmi/id/board_name)" ]
then
    # Samsung Series 9 (2012) "razor"
    SKU="razor"
    ROOT_DEVICE=/dev/sda
    EFI_PARTITION="${ROOT_DEVICE}1"
    SWAP_PARTITION="${ROOT_DEVICE}2"
    ROOT_PARTITION="${ROOT_DEVICE}3"
    SCRIPTS=(
        "https://pxe.tirefireind.us/scripts/systemd-networkd.sh"
        "https://pxe.tirefireind.us/scripts/systemd-timesyncd.sh"
        "https://pxe.tirefireind.us/scripts/root.sh"
        "https://pxe.tirefireind.us/scripts/autoconsole.sh"
    )
elif [ -e "/dev/nvme0n1" ] && [ 1024209543168 -eq $(blockdev --getsize64 /dev/nvme0n1) ] && \
     [ 'Dell Inc.' == "$(cat /sys/class/dmi/id/board_vendor)" ] && \
     [ 'XPS 15 9550' == "$(cat /sys/class/dmi/id/product_name)" ] && \
     [ '/26Y7QC2/CN1296368Q00A2/' == "$(cat /sys/class/dmi/id/board_serial)" ] && \
     [ '26Y7QC2' == "$(cat /sys/class/dmi/id/chassis_serial)" ]
then
    # Dell XPS 15 9550 (2016) "stormclad"
    SKU="silverline"
    HOSTNAME="silverline"
    ROOT_DEVICE=/dev/nvme0n1
    EFI_PARTITION="${ROOT_DEVICE}p1"
    SWAP_PARTITION="${ROOT_DEVICE}p2"
    ROOT_PARTITION="${ROOT_DEVICE}p3"
    SCRIPTS=(
        "https://pxe.tirefireind.us/scripts/arrdem.sh"
#        "https://pxe.tirefireind.us/scripts/workstation.sh"
    )
elif [ -e "/dev/nvme0n1" ] && [ 29260513280 -eq $(blockdev --getsize64 /dev/nvme0n1) ] && \
     [ -e "/dev/sda" ] && [ 1000204886016 -eq $(blockdev --getsize64 /dev/sda) ] && \
     [ 'AB350N-Gaming WIFI-CF' == "$(cat /sys/class/dmi/id/board_name)" ]
then
    # The Mk. 0 "modes of thought" (2018)
    SKU="mode"
    ROOT_DEVICE=/dev/nvme0n1
    EFI_PARTITION="${ROOT_DEVICE}p1"
    SWAP_PARTITION=""
    ROOT_PARTITION="${ROOT_DEVICE}p2"
    UNATTENDED=1  # Auto-install
    SCRIPTS=(
        "https://pxe.tirefireind.us/scripts/systemd-networkd.sh"
        "https://pxe.tirefireind.us/scripts/systemd-timesyncd.sh"
        "https://pxe.tirefireind.us/scripts/root.sh"
        "https://pxe.tirefireind.us/scripts/autoconsole.sh"
        "https://pxe.tirefireind.us/scripts/tickertape.sh"
        "https://pxe.tirefireind.us/scripts/ryzen-hacks.sh"
        "https://pxe.tirefireind.us/scripts/kubelet.sh"
    )
    EXTRAPKGS=('tickertape')
elif [ -e "/dev/nvme0n1" ] && [ 1000204886016 -eq $(blockdev --getsize64 /dev/nvme0n1) ] && \
     [ -e "/dev/sda" ] && [ 2000398934016 -eq $(blockdev --getsize64 /dev/sda) ] && \
     [ 'A520I AC' == "$(cat /sys/class/dmi/id/board_name)" ]
then
    SKU="mode2"
    ROOT_DEVICE=/dev/nvme0n1
    EFI_PARTITION="${ROOT_DEVICE}p1"
    SWAP_PARTITION=""
    ROOT_PARTITION="${ROOT_DEVICE}p2"
    UNATTENDED=1  # Auto-install
    SCRIPTS=(
        "https://pxe.tirefireind.us/scripts/systemd-networkd.sh"
        "https://pxe.tirefireind.us/scripts/systemd-timesyncd.sh"
        "https://pxe.tirefireind.us/scripts/root.sh"
        "https://pxe.tirefireind.us/scripts/autoconsole.sh"
        "https://pxe.tirefireind.us/scripts/tickertape.sh"
        "https://pxe.tirefireind.us/scripts/ryzen-hacks.sh"
        "https://pxe.tirefireind.us/scripts/kubelet.sh"
    )
    EXTRAPKGS=('tickertape')
elif [ 'ThinkPad T14s Gen 3' == "$(cat /sys/class/dmi/id/product_family)" ] && \
     [ -e '/dev/nvme0n1' ] && [ 2048408248320 -eq $(blockdev --getsize64 /dev/nvme0n1) ]
then
    # Lenovo T14s G3 (2023) "hal"
    SKU="hal"
    HOSTNAME="hal"
    ROOT_DEVICE=/dev/nvme0n1
    EFI_PARTITION="${ROOT_DEVICE}p1"
    SWAP_PARTITION="${ROOT_DEVICE}p2"
    ROOT_PARTITION="${ROOT_DEVICE}p3"
    SCRIPTS=(
        "https://pxe.tirefireind.us/scripts/arrdem.sh"
        # "https://pxe.tirefireind.us/scripts/workstation.sh"
    )
elif [ 'MS-7C95' == "$(cat /sys/class/dmi/id/product_name)" ] && \
     [ -e '/dev/nvme0n1' ] && [ 1000204886016 -eq $(blockdev --getsize64 /dev/nvme0n1) ]
then
    # Ryzen 5600G / MSI NAS build (2023) "heiroglyph"
    SKU="heiroglyph"
    HOSTNAME="heiroglyph"
    ROOT_DEVICE=/dev/nvme0n1
    EFI_PARTITION="${ROOT_DEVICE}p1"
    SWAP_PARTITION=""
    ROOT_PARTITION="${ROOT_DEVICE}p2"
    SCRIPTS=(
        "https://pxe.tirefireind.us/scripts/systemd-networkd.sh"
        "https://pxe.tirefireind.us/scripts/systemd-timesyncd.sh"
        "https://pxe.tirefireind.us/scripts/root.sh"
        "https://pxe.tirefireind.us/scripts/autoconsole.sh"
        "https://pxe.tirefireind.us/scripts/tickertape.sh"
    )
else
    _fail "ERROR: Unknown SKU"
fi

if [ -z "${UNATTENDED:-}" ]; then
    echo "To continue with installing a ${SKU}, hit enter"
    read
fi

# For some reason, this is super flakey. Sigh.
for _ in $(seq 1 5); do
    if pacman-key --init && pacman-key --populate; then
        break
    else
        umount -f /etc/pacman.d/gnupg
        rm -rf /etc/pacman.d/gnupg
    fi
done

# Install proquint and use it to compute a hostname as needed
curl 'https://ton.tirefireind.us/qint' -o qint && chmod +x ./qint
: "${HOSTNAME:=$(./qint -g)}"

if [ 'archlinux' == "${HOSTNAME:-archlinux}" ]; then
    _fail "Failed to configure a new hostname"
fi

# Dig the default interface out
DEFAULT_IFACE=$(awk '$2 == 00000000 { print $1 }' /proc/net/route)

# We use the MAC address of the default interface as the ID 'primary key' for a device
HWID=$(ip address show dev ${DEFAULT_IFACE} | awk '/ether/ {print tolower($2);}')

# Size of the EFI offset (in MiB)
# FIXME: This is a magic constant. Where is it from?
EFIOFFSET=1

# Size of the EFI partition (in MiB)
EFISIZE=300

# Compute the size (in MB) of main memory for use as the swap size, capped to 8GiB.
if [ ! -z "${SWAP_PARTITION}" ]; then
    SWAPSIZE=$(\
    awk '\
function ceil(x) {return int(x)+(x>int(x))};
function min(x,y) {return x<y?x:y;};
/MemTotal:/ {print min(ceil($2 / 1024) + 301, 8*1024);}
' /proc/meminfo
)
fi

# Reload the partition table, just in case we're rerunning
partprobe "${ROOT_DEVICE}"

# Clean out the original partition table, if any
wipefs -a "${ROOT_DEVICE}"

if [ ! -z "${SWAP_PARTITION}" ]; then
    # Lay down a standard partition table with swap
    parted -a optimal "${ROOT_DEVICE}" <<EOF
mklabel gpt
mkpart "EFI system partition" fat32 ${EFIOFFSET}MiB $(($EFIOFFSET + $EFISIZE))MiB
set 1 esp on
mkpart "swap partition" linux-swap $(($EFIOFFSET + $EFISIZE + 1))MiB $(($EFIOFFSET + $EFISIZE + $SWAPSIZE + 1))MiB
mkpart "root partition" ext4 $(($EFIOFFSET + $EFISIZE + $SWAPSIZE + 2))MiB 100%
EOF

else
    parted -a optimal "${ROOT_DEVICE}" <<EOF
mklabel gpt
mkpart "EFI system partition" fat32 ${EFIOFFSET}MiB $(($EFIOFFSET + $EFISIZE))MiB
set 1 esp on
mkpart "root partition" ext4 $(($EFIOFFSET + $EFISIZE + 1))MiB 100%
EOF
fi

# Apply formatting
mkfs.fat "${EFI_PARTITION}"
if [ ! -z "${SWAP_PARTITION}" ]; then
    mkswap "${SWAP_PARTITION}"
fi
mkfs.ext4 -F "${ROOT_PARTITION}"

# Mount the image for initialization
mount "${ROOT_PARTITION}" /mnt
mount --mkdir "${EFI_PARTITION}" /mnt/boot
if [ ! -z "${SWAP_PARTITION}" ]; then
    swapon "${SWAP_PARTITION}"
fi

# Configure pacman
curl https://mirror.tirefireind.us/archlinux/tirefireind/os/x86_64/tfi-pacman-mirrorlist-0.0.1-2-any.pkg.tar.zst -o tfi-pacman-mirrorlist-0.0.1-2-any.pkg.tar.zst
# I never joke about my work 007
yes 'y' | pacman -U tfi-pacman-mirrorlist-0.0.1-2-any.pkg.tar.zst

cat <<EOF > /etc/pacman.conf
[options]
CleanMethod = KeepInstalled
Architecture = auto

UseSyslog
CheckSpace

SigLevel = Required DatabaseOptional
LocalFileSigLevel = Optional

[core]
Include = /etc/pacman.d/mirrorlist

[extra]
Include = /etc/pacman.d/mirrorlist

[tirefireind]
SigLevel = Optional TrustAll
Include = /etc/pacman.d/mirrorlist

[arrdem-$(uname -m)]
SigLevel = Optional TrustAll
Server = http://mirror.tirefireind.us/archlinux/arrdem/os/$(uname -m)

[arrdem-any]
SigLevel = Optional TrustAll
Server = http://mirror.tirefireind.us/archlinux/arrdem/os/any
EOF

case $(cat /proc/cpuinfo | awk '/vendor_id/ {print $3;}' | uniq) in
     AuthenticAMD)
         EXTRAPKGS=("${EXTRAPKGS[@]}" 'amd-ucode')
         fwinitrd=/amd-ucode.img
         ;;
     GenuineIntel)
         EXTRAPKGS=("${EXTRAPKGS[@]}" 'intel-ucode')
         fwinitrd=/intel-ucode.img
         ;;
     *)
         _fail "Unknown cpuid! Consumt /proc/cpuinfo"
         ;;
esac

# Pacstrap

# "${EXTRAPKGS[@]}"
INSTALLPKGS=(
    tfi-pacman-mirrorlist
    base
    linux
    linux-firmware
    python3
    openssh
    curl
    emacs-nox
    iptables-nft
)
IGNOREPKGS=(
    pacman-mirrorlists
    iptables
)
PACMANARGS=()
for i in "${IGNOREPKGS[@]}"; do
    PACMANARGS=("${PACMANARGS[@]}" '--ignore' "$i")
done
PACMANARGS=("${PACMANARGS[@]}" "${INSTALLPKGS[@]}" "${EXTRAPKGS[@]}")
pacstrap -P /mnt "${PACMANARGS[@]}" || _fail "ERROR: Exhausted retries while pacstrapping"

# Bootstrap the fstab
genfstab -U /mnt >> /mnt/etc/fstab

# Boostrap the resolvconf symlink before anything else can monkey with it
[ ! -L /mnt/etc/resolv.conf ] && (
    rm -f /mnt/etc/resolv.conf
    ln -s /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
)

# Arch-chroot spawns a shell, so we need to script that
arch-chroot /mnt <<EOF
set -ex

# Set the hostname
echo "${HOSTNAME}" > /etc/hostname

# Time
ln -sf /usr/share/zoneinfo/America/Denver /etc/localtime
hwclock --systohc

# Locale
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" > /etc/locale.conf

# Configure ssh
systemctl enable sshd

# Boot loader
bootctl --esp-path=/boot install

# Configure the bootctl menu
cat > /boot/loader/loader.conf <<'FOOF'
default      arch.conf
timeout      4
console-mode max
editor       no
FOOF

# Configure the Arch install as bootable
cat > /boot/loader/entries/arch.conf <<FOOF
title   Arch Linux
linux   /vmlinuz-linux
initrd  $fwinitrd
initrd  /initramfs-linux.img
options root="$(blkid $ROOT_PARTITION | sed 's/ /\n/g' | grep -e '^UUID=' | sed 's/"//g')" rw
option  rcu_nocbs=0-$(($(nproc)-1))
FOOF

if false; then
   # Create a way to re-PXE
   # FIXME: Move this into an Arch package
   curl -o /boot/ipxe.efi http://pxe.tirefireind.us/tftp/ipxe.efi
   cat > /boot/loader/entries/ipxe.conf <<'FOOF'
title  iPXE
efi    /ipxe.efi
FOOF

fi

tmpf=$(mktemp)
for url in ${SCRIPTS[@]}; do
  eval "\$(curl "\$url")"
done

EOF

if [ $(sha256sum /etc/pacman.d/mirrorlist | awk '{print $1}') != $(sha256sum /mnt/etc/pacman.d/mirrorlist | awk '{print $1}') ]; then
    _fail "TireFire mirrorlist not installed"
fi

if [ ! -z "${UNATTENDED:-}" ]; then
   systemctl reboot
fi
