{
  config,
  lib,
  pkgs,
  options,
  ...
}:
let
  inherit (lib)
    mkEnableOption
    mkIf
    mkOption
    types
    ;
  cfg = config.modules.server.rustypaste;
  opts = options.modules.server.rustypaste;
  toml = pkgs.formats.toml { };
in
{
  options.modules.server.rustypaste = {
    enable = mkEnableOption "rustypaste, a pastebin alternative";

    authTokenFile = mkOption {
      type = types.str;
      default = "";
    };

    deleteTokenFile = mkOption {
      type = types.str;
      default = "";
    };

    port = mkOption {
      type = types.port;
      default = 8000;
      description = "The port rustypaste should listen on.";
    };

    openFirewall = mkOption {
      type = types.bool;
      default = false;
      description = "Whether to open the specified port.";
    };

    address = mkOption {
      type = types.nonEmptyStr;
      default = "127.0.0.1";
      description = "The address rustypaste should listen on.";
    };

    package = mkOption {
      type = types.package;
      default = pkgs.rustypaste;
    };

    user = mkOption {
      type = types.str;
      default = "rustypaste";
      description = "User account under which rustypaste runs.";
    };

    group = mkOption {
      type = types.str;
      default = "rustypaste";
      description = "Group under which rustypaste runs.";
    };

    settings = lib.mkOption {
      inherit (toml) type;
      default = {
        config.refresh_rate = "1y";
        server = {
          address = "${cfg.address}:${toString cfg.port}";
          max_content_length = "10MB";
          upload_path = cfg.dataDir;
        };
        paste = {
          default_extension = "txt";
        };
      };
      defaultText = "Refer to https://github.com/orhun/rustypaste/blob/master/config.toml";
      apply = lib.recursiveUpdate opts.settings.default;
    };

    dataDir = lib.mkOption {
      type = types.nonEmptyStr;
      default = "/var/lib/rustypaste";
      description = "Where rustypaste stores uploaded files.";
    };

    settingsFile = lib.mkOption {
      type = types.path;
      default = toml.generate "rustypaste.toml" cfg.settings;
    };
  };

  config = mkIf cfg.enable {
    networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];

    systemd.tmpfiles.rules = [
      "d ${cfg.dataDir} 0700 ${cfg.user} ${cfg.group}"
    ];

    systemd.services.rustypaste = {
      enable = true;
      after = [ "network.target" ];
      wantedBy = [ "multi-user.target" ];

      environment = {
        "CONFIG" = cfg.settingsFile;
        "AUTH_TOKENS_FILE" = mkIf (cfg.authTokenFile != "") cfg.authTokenFile;
        "DELETE_TOKENS_FILE" = mkIf (cfg.deleteTokenFile != "") cfg.deleteTokenFile;
      };
      serviceConfig = {
        Type = "simple";
        User = cfg.user;
        Group = cfg.group;
        WorkingDirectory = cfg.dataDir;
        ExecStart = "${cfg.package}/bin/rustypaste";
        Restart = "on-failure";
        PrivateDevices = true;
        PrivateTmp = true;
        ProtectSystem = "full";
        ReadWritePaths = cfg.dataDir;
        ReadOnlyPaths = lib.concatStringsSep " " [
          cfg.settingsFile
          cfg.authTokenFile
          cfg.deleteTokenFile
        ];
        IPAddressAllow = "any";
      };
    };

    users.users = mkIf (cfg.user == "rustypaste") {
      rustypaste = {
        useDefaultShell = true;
        group = cfg.group;
        isSystemUser = true;
      };
    };

    users.groups = mkIf (cfg.group == "rustypaste") {
      rustypaste = { };
    };
  };
}
