{ pkgs, ... }:

let
  sshKeyPath = "/home/lebowski/.ssh/id_ed25519";
  sshKeyName = "V3";
  serverName = "builder";
  serverType = "ccx43";
  snapshotType = "ccx13";
  snapshotDesc = "nixos-builder";
  location = "nbg1";
  flakeDir = "/home/lebowski/NixOS";

  sshCmd = "ssh -o StrictHostKeyChecking=no -o BatchMode=yes -i ${sshKeyPath}";

  # Boot a builder from the NixOS snapshot
  builder-up = pkgs.writeShellApplication {
    name = "builder-up";
    runtimeInputs = with pkgs; [ hcloud openssh ];
    text = ''
      if hcloud --context builder server describe "${serverName}" &>/dev/null; then
        IP=$(hcloud --context builder server ip "${serverName}")
        echo "Builder already running at $IP"
        echo "  builder-ssh"
        exit 0
      fi

      SNAPSHOT_ID=$(hcloud --context builder image list --type snapshot -o noheader -o columns=id,description | grep "${snapshotDesc}" | awk '{print $1}' | head -1)

      if [ -z "$SNAPSHOT_ID" ]; then
        echo "ERROR: No snapshot '${snapshotDesc}' found."
        echo "  Create one with: builder-snapshot"
        exit 1
      fi

      echo "==> Creating ${serverType} in ${location}..."
      hcloud --context builder server create \
        --name "${serverName}" \
        --type "${serverType}" \
        --image "$SNAPSHOT_ID" \
        --location "${location}" \
        --ssh-key "${sshKeyName}"

      IP=$(hcloud --context builder server ip "${serverName}")

      echo "==> Waiting for SSH..."
      for i in $(seq 1 30); do
        if ${sshCmd} "root@''${IP}" true 2>/dev/null; then
          break
        fi
        if [ "$i" -eq 30 ]; then
          echo "ERROR: SSH did not become available after 150s"
          exit 1
        fi
        sleep 5
      done

      ssh-keygen -R "$IP" 2>/dev/null || true
      ssh-keyscan -H "$IP" >> ~/.ssh/known_hosts 2>/dev/null

      echo ""
      echo "=== Builder ready ==="
      IP=$(hcloud --context builder server ip "${serverName}")
      ssh -i "${sshKeyPath}" -t "root@$IP" "tmux new-session -A -s build"
    '';
  };

  # SSH into the builder
  builder-ssh = pkgs.writeShellApplication {
    name = "builder-ssh";
    runtimeInputs = with pkgs; [ hcloud openssh ];
    text = ''
      if ! hcloud --context builder server describe "${serverName}" &>/dev/null; then
        echo "No builder found. Run builder-up first."
        exit 1
      fi

      IP=$(hcloud --context builder server ip "${serverName}")
      ssh -i "${sshKeyPath}" -t "root@$IP" "tmux new-session -A -s build"
    '';
  };

  # Tear down the builder
  builder-down = pkgs.writeShellApplication {
    name = "builder-down";
    runtimeInputs = with pkgs; [ hcloud openssh ];
    text = ''
      if hcloud --context builder server describe "${serverName}" &>/dev/null; then
        IP=$(hcloud --context builder server ip "${serverName}")
        echo "==> Deleting '${serverName}' ($IP)..."
        hcloud --context builder server delete "${serverName}"
        ssh-keygen -R "$IP" 2>/dev/null || true
        echo "    Done."
      else
        echo "No builder found."
      fi
    '';
  };

  # Create or update the NixOS builder snapshot
  # 1. Spins up a cheap server
  # 2. Installs NixOS via nixos-anywhere
  # 3. Rebuilds with latest config
  # 4. Sets up credentials (attic, git)
  # 5. Cleans up, snapshots, deletes server
  builder-snapshot = pkgs.writeShellApplication {
    name = "builder-snapshot";
    runtimeInputs = with pkgs; [ hcloud openssh nixos-anywhere ];
    text = ''
      TMP_SERVER="snapshot-tmp"

      MISSING=""
      [ -z "''${ATTIC_TOKEN:-}" ] && MISSING="$MISSING ATTIC_TOKEN"
      [ -z "''${FORGEJO_TOKEN:-}" ] && MISSING="$MISSING FORGEJO_TOKEN"
      [ -z "''${CACHIX_TOKEN:-}" ] && MISSING="$MISSING CACHIX_TOKEN"

      if [ -n "$MISSING" ]; then
        echo "ERROR: Missing environment variables:$MISSING"
        echo ""
        echo "  export ATTIC_TOKEN=<attic-jwt-token>"
        echo "  export FORGEJO_TOKEN=<forgejo-access-token>"
        echo "  export CACHIX_TOKEN=<cachix-auth-token>"
        exit 1
      fi

      echo "==> Creating ${snapshotType} for snapshot..."
      hcloud --context builder server create \
        --name "$TMP_SERVER" \
        --type "${snapshotType}" \
        --image ubuntu-24.04 \
        --location "${location}" \
        --ssh-key "${sshKeyName}"

      IP=$(hcloud --context builder server ip "$TMP_SERVER")

      echo "==> Waiting for SSH..."
      for i in $(seq 1 30); do
        if ${sshCmd} "root@''${IP}" true 2>/dev/null; then
          break
        fi
        if [ "$i" -eq 30 ]; then
          echo "ERROR: SSH did not become available"
          hcloud --context builder server delete "$TMP_SERVER"
          exit 1
        fi
        sleep 5
      done

      ssh-keygen -R "$IP" 2>/dev/null || true
      ssh-keyscan -H "$IP" >> ~/.ssh/known_hosts 2>/dev/null

      echo "==> Installing NixOS via nixos-anywhere..."
      nixos-anywhere --flake "${flakeDir}#builder" "root@$IP"

      echo "==> Waiting for NixOS to boot..."
      sleep 15
      ssh-keygen -R "$IP" 2>/dev/null || true
      for i in $(seq 1 30); do
        if ${sshCmd} "root@''${IP}" true 2>/dev/null; then
          break
        fi
        sleep 5
      done
      ssh-keyscan -H "$IP" >> ~/.ssh/known_hosts 2>/dev/null

      echo "==> Rebuilding with latest config..."
      nixos-rebuild switch --flake "${flakeDir}#builder" --target-host "root@$IP"

      echo "==> Setting up credentials..."
      ${sshCmd} "root@''${IP}" "attic login axiomania https://cache.axiomania.org ''${ATTIC_TOKEN}"
      ${sshCmd} "root@''${IP}" bash -s -- "''${FORGEJO_TOKEN}" <<'SETUP'
        TOKEN="$1"
        git config --global credential.https://git.axiomania.org.helper store
        echo "https://lebowski:$TOKEN@git.axiomania.org" > /root/.git-credentials
        chmod 600 /root/.git-credentials
SETUP
      ${sshCmd} "root@''${IP}" bash -s -- "''${CACHIX_TOKEN}" <<'CACHIX'
        echo "$1" | cachix authtoken --stdin
CACHIX

      echo "==> Garbage collecting..."
      ${sshCmd} "root@''${IP}" "nix-collect-garbage -d && nix store optimise"

      # ── Delete old snapshot(s) ──
      OLD=$(hcloud --context builder image list --type snapshot -o noheader -o columns=id,description | grep "${snapshotDesc}" | awk '{print $1}')
      if [ -n "$OLD" ]; then
        echo "==> Deleting old snapshot(s)..."
        echo "$OLD" | while read -r sid; do
          hcloud --context builder image delete "$sid"
        done
      fi

      echo "==> Shutting down for clean snapshot..."
      hcloud --context builder server shutdown "$TMP_SERVER"
      sleep 10

      echo "==> Creating snapshot..."
      hcloud --context builder server create-image --type snapshot --description "${snapshotDesc}" "$TMP_SERVER"

      echo "==> Deleting temporary server..."
      hcloud --context builder server delete "$TMP_SERVER"
      ssh-keygen -R "$IP" 2>/dev/null || true

      echo ""
      echo "=== Snapshot '${snapshotDesc}' created ==="
      echo "  Use 'builder-up' to spin up a builder."
    '';
  };

in
{
  environment.systemPackages = [
    builder-up
    builder-ssh
    builder-down
    builder-snapshot
    pkgs.hcloud
  ];
}
