{
  config,
  lib,
  pkgs,
  ...
}:

{
  imports = [ ];

  options.me = {
    shadps4.enable = lib.mkOption {
      type = lib.types.bool;
      default = false;
      example = true;
      description = "Whether we want to install shadps4.";
    };
  };

  config = lib.mkIf (config.me.shadps4.enable && config.me.graphical) {
    environment.systemPackages = with pkgs; [
      shadps4
    ];

    me.install.user.talexander.file = {
      ".local/share/shadPS4/config.toml" = {
        source = ./files/config.toml;
      };
    };

    environment.persistence."/persist" = lib.mkIf (config.me.mountPersistence) {
      hideMounts = true;
      users.talexander = {
        directories = [
          {
            # Location of ROMs.
            directory = ".local/share/shadPS4/games";
            user = "talexander";
            group = "talexander";
            mode = "0755";
          }
          {
            # Firmware.
            directory = ".local/share/shadPS4/sys_modules";
            user = "talexander";
            group = "talexander";
            mode = "0755";
          }
          {
            # Game saves.
            directory = ".local/share/shadPS4/savedata";
            user = "talexander";
            group = "talexander";
            mode = "0755";
          }
          {
            # DLC.
            directory = ".local/share/shadPS4/addcont";
            user = "talexander";
            group = "talexander";
            mode = "0755";
          }
        ];
        files = [
          {
            # play times and recently played
            file = ".local/share/shadPS4/play_time.txt";
            parentDirectory = {
              mode = "0755";
            };
          }
        ];
      };
    };

    environment.persistence."/state" = lib.mkIf (config.me.mountPersistence) {
      hideMounts = true;
      users.talexander = {
        directories = [
          {
            # Cache.
            directory = ".local/share/shadPS4/data";
            user = "talexander";
            group = "talexander";
            mode = "0755";
          }
        ];
      };
    };

    nixpkgs.overlays = [
      (final: prev: {
        shadps4 = prev.shadps4.overrideAttrs (old: {
          version = "0.11.0";
          src = final.fetchFromGitHub {
            owner = "AzaharPlus";
            repo = "shadPS4Plus";
            tag = "SHAD_PS4_PLUS_0_11_0";
            hash = "sha256-puyINtFBTdMkOE2E9OnUlZ526vXHCWyKIWsZBaojQRk=";
            fetchSubmodules = true;
          };
        });
      })

      (final: prev: {
        pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
          (python-final: python-prev: {
            shiboken2 = python-prev.shiboken2.overrideAttrs (old: {
              cmakeFlags = old.cmakeFlags ++ [
                # Fix build with cmake>=4
                (lib.strings.cmakeFeature "CMAKE_POLICY_VERSION_MINIMUM" "3.5")
                # "-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
              ];
            });
            pyside2 = python-prev.pyside2.overrideAttrs (old: {
              cmakeFlags = old.cmakeFlags ++ [
                # Fix build with cmake>=4
                (lib.strings.cmakeFeature "CMAKE_POLICY_VERSION_MINIMUM" "3.5")
                # "-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
              ];
            });
            pyside2-tools = python-prev.pyside2-tools.overrideAttrs (old: {
              cmakeFlags = old.cmakeFlags ++ [
                # Fix build with cmake>=4
                (lib.strings.cmakeFeature "CMAKE_POLICY_VERSION_MINIMUM" "3.5")
                # "-DCMAKE_POLICY_VERSION_MINIMUM=3.5"
              ];
            });
          })
        ];
      })
    ];
  };
}
