{ pkgs
, lib
, config
, ... }: with lib; let
  cfg = config.global.gui;

  intel = cfg.type == "intel" || (cfg.type == "prime" && config.hardware.nvidia.prime.intelBusId != "");
  amdgpu = cfg.type == "amdgpu" || (cfg.type == "prime" && config.hardware.nvidia.prime.amdgpuBusId != "");
  nvidia = cfg.type == "nvidia" || cfg.type == "prime";
in {
  imports = [
    ./plymouth.nix
    ./greetd.nix
  ];

  options.global.gui = {
    enable = mkEnableOption "various setup required for GUI and support software";
    session = mkEnableOption "software required for a graphical session" // { default = true; };
    type = mkOption {
      type = with types; nullOr (enum [ "intel" "amdgpu" "nvidia" "prime" ]);
      default = null;
      description = "type of graphics acceleration used";
    };
    arc = mkOption {
      type = with types; nullOr str;
      default = null;
      description = "intel arc PCI ID if installed, enables toggling the arc before boot";
    };
  };

  config = mkIf cfg.enable {
    hardware.opengl = {
      enable = true;
      driSupport = true;
      driSupport32Bit = true;

      # https://nixos.wiki/wiki/Accelerated_Video_Playback
      extraPackages = with pkgs; optionals intel [
        intel-media-driver # LIBVA_DRIVER_NAME=iHD
        vaapiIntel         # LIBVA_DRIVER_NAME=i965 (older but works better for Firefox/Chromium)
        vaapiVdpau
        libvdpau-va-gl
        intel-compute-runtime
      ] ++ optional nvidia nvidia-vaapi-driver;
    };

    services.xserver.videoDrivers =
    optional nvidia "nvidia" ++
    optional (cfg.type == "amdgpu") "amdgpu";
    # inhibits default display manager
    services.xserver.displayManager.startx.enable = mkDefault true;

    hardware.nvidia = mkIf nvidia {
      modesetting.enable = true;
      nvidiaSettings = true;

      prime = mkIf (cfg.type == "prime") {
        offload = {
          enable = true;
          enableOffloadCmd = true;
        };
      };

      powerManagement.enable = false;
      powerManagement.finegrained = false;
      open = false;
    };

    specialisation.integratedGraphics = mkIf (cfg.type == "prime") {
      configuration = {
        global.gui.type = mkForce (if intel then "intel" else if amdgpu then "amdgpu" else "prime");
        boot.blacklistedKernelModules = [ "nouveau" ];
      };
    };

    specialisation.withArc = mkIf (cfg.arc != null) {
      configuration = {
        global.gui.arc = mkForce null;
        powerManagement.cpuFreqGovernor = mkForce "performance";
      };
    };

    specialisation.withArcFull = mkIf (cfg.arc != null) {
      configuration = {
        global.gui.arc = mkForce null;
        powerManagement.cpuFreqGovernor = mkForce "performance";

        # set DRI_PRIME in profile to always enable offloading
        environment.variables.DRI_PRIME = "1";
        services.greetd.settings.default_session.command = ''
          # regreet is buggy with offload enabled so we turn it off
          env DRI_PRIME=0 ${pkgs.dbus}/bin/dbus-run-session \
          ${getExe pkgs.cage} ${escapeShellArgs config.programs.regreet.cageArgs} -- \
          ${getExe config.programs.regreet.package}
        '';
      };
    };

    boot.initrd.kernelModules =
    optional amdgpu "amdgpu" ++
    optional intel "i915" ++
    optional (cfg.arc != null) "vfio-pci";

    boot.extraModprobeConfig = mkIf (cfg.arc != null) ''
      softdep drm pre: vfio-pci
      options vfio-pci ids=${cfg.arc}
    '';

    boot.kernelParams = optional intel "i915.fastboot=1";
  };
}