#!/usr/bin/env nix-shell
#!nix-shell -i bash -p bash jq envsubst wget utillinux gptfdisk cryptsetup lvm2 dosfstools e2fsprogs mkpasswd
# shellcheck shell=bash
set -Eeuo pipefail

end="\033[0m"

green() {
  green_color="\033[0;32m"
  echo -e "${green_color}${1}${end}"
}

yellow() {
  yellow_color="\033[0;33m"
  echo -e "${yellow_color}${1}${end}"
}

blue() {
  blue_color="\033[0;34m"
  echo -e "${blue_color}${1}${end}"
}

red() {
  red_color="\033[0;31m"
  echo -e "${red_color}${1}${end}"
}

usage() {
  red "Missing input argument $1.\n"
  cat <<EOF
Usage:
    install.sh <HOST_NAME> <DEVICE>

      Arguments
        HOST_NAME         The networking.hostName of the installation. Something like 'velhinho-nixos'.
        DEVICE            The LUKS device where to install to. Use lsblk or similar tools to get it's name.

Examples:
    Download install.sh and run it with 'velhinho-nixos' as hostName and '/dev/sda' as disk device:
        curl https://euandre.org/dotfiles/nixos/install.sh > install.sh
        chmod +x install.sh
        ./install.sh velhinho-nixos /dev/sda
EOF
}

HOST_NAME="${1:-}"
DEVICE="${2:-}"

[[ -z "${HOST_NAME}" ]] && {
  usage 'HOST_NAME'
  exit 2
}

[[ -z "${DEVICE}" ]] && {
  usage 'DEVICE'
  exit 2
}


if [[ "${DEVICE}" = '/dev/sda' ]]; then
  export DEVICE_P2="${DEVICE}2"
  export DEVICE_P3="${DEVICE}3"
fi

if [[ "${DEVICE}" = '/dev/nvme0n1' ]]; then
  export DEVICE_P2="${DEVICE}p2"
  export DEVICE_P3="${DEVICE}p3"
fi

SERVER="https://euandre.org/dotfiles/nixos"

yellow "Downloading Nix files..."
TMP_DIR="$(mktemp -d)"
wget -O "${TMP_DIR}/configuration.nix" "${SERVER}/configuration.nix"
wget -O "${TMP_DIR}/template.nix"      "${SERVER}/template.nix"
green "Done."

yellow "Creating content of '/etc/nixos/local-configuration.nix'..."
export HOST_NAME
export DEVICE
envsubst < "${TMP_DIR}/template.nix" > "${TMP_DIR}/local-configuration.nix"
blue "$(cat "${TMP_DIR}/local-configuration.nix")"
read -p "Confirm content of '/etc/nixos/local-configuration.nix'? (y/N) " -n 1 -r
echo # Move to a new line
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  red "Unconfirmed content of '/etc/nixos/local-configuration.nix'."
  red "Exitting."
  exit 1
fi
green "Done."

yellow "Wiping '${DEVICE}'and partitioning it..."
# Derived from:
# https://www.rodsbooks.com/gdisk/sgdisk-walkthrough.html
# https://chris-martin.org/2015/installing-nixos
wipefs --all --force "${DEVICE}"
sgdisk --clear    "${DEVICE}" # Unclear the v
sgdisk --zap-all  "${DEVICE}" # order here  ^
sgdisk --mbrtogpt "${DEVICE}"
sgdisk --new 1:2048:4095    --change-name 1:"BIOS boot partition" --typecode 1:EF02 "${DEVICE}"
sgdisk --new 2:4096:1028095 --change-name 2:"EFI System"          --typecode 2:EF00 "${DEVICE}"
sgdisk --new 3:1028096:0    --change-name 3:"Linux LVM"           --typecode 3:8E00 "${DEVICE}"
sgdisk --print "${DEVICE}"
green "Done."

yellow "Configuring LUKS encryption on '${DEVICE_P3}'..."
cryptsetup luksFormat "${DEVICE_P3}"
cryptsetup luksOpen "${DEVICE_P3}" enc-pv
pvcreate /dev/mapper/enc-pv
vgcreate vg /dev/mapper/enc-pv
lvcreate -n swap vg -L 10G
lvcreate -n root vg -l 100%FREE
green "Done."

yellow "Formatting '${DEVICE_P2}'..."
mkfs.vfat -n BOOT "${DEVICE_P2}"
mkfs.ext4 -L root /dev/vg/root
mkswap -L swap /dev/vg/swap
green "Done."

yellow "Mounting and activating swap..."
mount /dev/vg/root /mnt
mkdir /mnt/boot
mount "${DEVICE_P2}" /mnt/boot
swapon /dev/vg/swap
green "Done."

yellow "Installing NixOS!"
nixos-generate-config --root /mnt
nixos-install
green "Done."

yellow "Shutting down..."
shutdown now
