{ config, lib, options, pkgs, ... }:
let
  packageName = "custom-nixos-vm";

  mergedSystemOption =
    with options.system;
    lib.mergeDefinitions
      build.loc
      build.type
      (lib.lists.forEach
        (
          builtins.filter
            (item:
              !(lib.path.hasPrefix ./. (/. + item.file)))
            build.definitionsWithLocations)
        (item: { inherit (item) file value; }));

  vanillaVM = mergedSystemOption.mergedValue.vm;
in {
  options =
  let
    vmVariantOptions = {
      virtualisation = {
        runAsRoot = lib.mkOption {
          type = lib.types.bool;
          default = false;
        };

        sharedHostKeys = lib.mkOption {
          type = lib.types.bool;
          default = false;
        };

        qemu.runInBackground = lib.mkOption {
          type = lib.types.bool;
          default = false;
        };
      };
    };
  in {
    virtualisation = {
      vmVariant = vmVariantOptions;
      vmVariantWithBootLoader = vmVariantOptions;
    };
  };

  config = {
    virtualisation =
      let
        extendVMConfig =
          vmVariant: {
            boot.loader.efi.efiSysMountPoint = lib.mkVMOverride "/boot";

            virtualisation = {
              runAsRoot = lib.mkIf vmVariant.virtualisation.sharedHostKeys true;

              sharedDirectories = lib.optionalAttrs (vmVariant.virtualisation.sharedHostKeys) {
                hostKeys =
                let
                  path = "/etc/ssh";
                in {
                  source = path;
                  target = path;
                };
              };
            };
          };

        virtualisation = config.virtualisation;
      in {
        vmVariant = extendVMConfig virtualisation.vmVariant;
        vmVariantWithBootLoader = extendVMConfig virtualisation.vmVariantWithBootLoader;
      };

    # Replace native `qemu` with `remote-viewer`
    system.build =
      {
        vm = lib.mkForce (
          (
            vm:
              if (vm.name == packageName)
              then
                vm
              else
                let
                  prefix =
                    lib.concatStringsSep " " (
                      lib.optionals config.virtualisation.runAsRoot (
                        ["sudo"] ++
                        lib.optional config.virtualisation.qemu.runInBackground "-b"));

                  suffix =
                    lib.concatStringsSep " " (
                      lib.optional
                        (!config.virtualisation.runAsRoot && config.virtualisation.qemu.runInBackground)
                        "&");

                  wrapped = pkgs.writeShellApplication {
                    name = "run-${config.system.name}-vm";
                    text = ''
                      ${prefix} ${vm}/bin/run-${config.system.name}-vm ${suffix}
                    '';
                  };
                in
                  pkgs.symlinkJoin {
                    name = packageName;
                    paths = [ wrapped ];
                  })
          vanillaVM);
      };
  };
}