# Build ISO image
#   nix build --extra-experimental-features nix-command --extra-experimental-features flakes .#iso.odo
#   output: result/iso/nixos.iso

# Run the ISO image
#   "$(nix-build '<nixpkgs>' --no-out-link -A 'qemu')/bin/qemu-system-x86_64" \
#        -accel kvm \
#        -cpu host \
#        -smp cores=8 \
#        -m 32768 \
#        -drive "file=$(nix-build '<nixpkgs>' --no-out-link -A 'OVMF.fd')/FV/OVMF.fd,if=pflash,format=raw,readonly=on" \
#        -drive if=pflash,format=raw,file="/tmp/OVMF_VARS.fd" \
#        -nic user,hostfwd=tcp::60022-:22 \
#        -boot order=d \
#        -cdrom "$(readlink -f ./result/iso/nixos.iso)" \
#        -display vnc=127.0.0.1:0
#
# doas cp "$(nix-build '<nixpkgs>' --no-out-link -A 'OVMF.fd')/FV/OVMF_VARS.fd" /tmp/OVMF_VARS.fd
# doas "$(nix-build '<nixpkgs>' --no-out-link -A 'qemu')/bin/qemu-system-x86_64" -accel kvm -cpu host -smp cores=8 -m 32768 -drive "file=$(nix-build '<nixpkgs>' --no-out-link -A 'OVMF.fd')/FV/OVMF.fd,if=pflash,format=raw,readonly=on" -drive if=pflash,format=raw,file="/tmp/OVMF_VARS.fd" -nic user,hostfwd=tcp::60022-:22 -boot order=d -cdrom /persist/machine_setup/nix/configuration/result/iso/nixos*.iso -display vnc=127.0.0.1:0

# Get a repl for this flake
#   nix repl --expr "builtins.getFlake \"$PWD\""

# TODO maybe use `nix eval --raw .#iso.odo.outPath`
# iso.odo.isoName == "nixos.iso"
# full path = <outPath> / iso / <isoName>

{
  description = "My system configuration";

  inputs = {
    impermanence.url = "github:nix-community/impermanence";
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    nixpkgs-b93b4e9b5.url = "github:NixOS/nixpkgs/b93b4e9b527904aadf52dba6ca35efde2067cbd4";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    lanzaboote = {
      url = "github:nix-community/lanzaboote/v0.4.2";

      # Optional but recommended to limit the size of your system closure.
      inputs.nixpkgs.follows = "nixpkgs";
    };
    zsh-histdb = {
      url = "path:flakes/zsh-histdb";

      # Optional but recommended to limit the size of your system closure.
      inputs.nixpkgs.follows = "nixpkgs";
    };
    ansible-sshjail = {
      url = "path:flakes/ansible-sshjail";

      # Optional but recommended to limit the size of your system closure.
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs =
    {
      self,
      nixpkgs,
      nixpkgs-b93b4e9b5,
      impermanence,
      home-manager,
      lanzaboote,
      zsh-histdb,
      ansible-sshjail,
      ...
    }@inputs:
    let
      base_x86_64_linux = rec {
        system = "x86_64-linux";
        specialArgs = {
          pkgs-b93b4e9b5 = import nixpkgs-b93b4e9b5 {
            inherit system;
          };
        };
        modules = [
          impermanence.nixosModules.impermanence
          home-manager.nixosModules.home-manager
          lanzaboote.nixosModules.lanzaboote
          {
            home-manager.useGlobalPkgs = true;
            home-manager.useUserPackages = true;
          }
          {
            nixpkgs.overlays = [
              zsh-histdb.overlays.default
              ansible-sshjail.overlays.default
            ];
          }
          ./configuration.nix
        ];
      };
      systems = {
        odo = {
          main = nixpkgs.lib.nixosSystem (
            base_x86_64_linux
            // {
              modules = base_x86_64_linux.modules ++ [
                ./hosts/odo
              ];
            }
          );
          iso = nixpkgs.lib.nixosSystem (
            base_x86_64_linux
            // {
              modules = base_x86_64_linux.modules ++ [
                ./hosts/odo
                (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix")
                # TODO: Figure out how to do image based appliances
                # (nixpkgs + "/nixos/modules/profiles/image-based-appliance.nix")
                {
                  isoImage.makeEfiBootable = true;
                  isoImage.makeUsbBootable = true;
                  me.buildingIso = true;
                }
              ];
            }
          );
        };
        neelix = {
          main = nixpkgs.lib.nixosSystem (
            base_x86_64_linux
            // {
              modules = base_x86_64_linux.modules ++ [
                ./hosts/neelix
              ];
            }
          );
          iso = nixpkgs.lib.nixosSystem (
            base_x86_64_linux
            // {
              modules = base_x86_64_linux.modules ++ [
                ./hosts/neelix
                (nixpkgs + "/nixos/modules/installer/cd-dvd/iso-image.nix")
                {
                  isoImage.makeEfiBootable = true;
                  isoImage.makeUsbBootable = true;
                  me.buildingIso = true;
                }
              ];
            }
          );
        };
      };
    in
    {
      nixosConfigurations.odo = systems.odo.main;
      iso.odo = systems.odo.iso.config.system.build.isoImage;
      nixosConfigurations.neelix = systems.neelix.main;
      iso.neelix = systems.neelix.iso.config.system.build.isoImage;
    };
}