{
  config,
  lib,
  ...
}: let
  mail_config = config.services.mailserver;

  postfixCfg = config.services.postfix;
  rspamdCfg = config.services.rspamd;
  rspamdSocket = "rspamd.service";
in {
  config = lib.mkIf (mail_config.enable) {
    services.rspamd = {
      enable = true;
      debug = mail_config.debug_mode;
      locals = {
        "milter_headers.conf" = {
          text = ''
            extended_spam_headers = yes;
          '';
        };
        "redis.conf" = {
          text = ''
            servers = "127.0.0.1:${toString mail_config.rspamd_redis_port}";
          '';
        };
        "classifier-bayes.conf" = {
          text = ''
            cache {
              backend = "redis";
            }
            min_learns = 5;
          '';
        };
        "dkim_signing.conf" = {
          text = ''
            # opendkim does this
            enabled = false;
          '';
        };
      };

      overrides = {
        "milter_headers.conf" = {
          text = ''
            extended_spam_headers = true;
          '';
        };
      };

      workers.rspamd_proxy = {
        type = "rspamd_proxy";
        bindSockets = [
          {
            socket = "/run/rspamd/rspamd-milter.sock";
            mode = "0664";
          }
        ];
        count = 1;
        extraConfig = ''
          milter = yes;
          timeout = 120s;

          upstream "local" {
            default = yes;
            self_scan = yes;
          }
        '';
      };
      workers.controller = {
        type = "controller";
        count = 1;
        bindSockets = [
          {
            socket = "/run/rspamd/worker-controller.sock";
            mode = "0666";
          }
        ];
        includes = [];
      };
    };

    services.redis.servers.rspamd = {
      enable = true;
      port = mail_config.rspamd_redis_port;
    };

    systemd.services.rspamd = {
      requires = ["redis-rspamd.service"];
      after = ["redis-rspamd.service"];
    };

    systemd.services.postfix = {
      after = [rspamdSocket];
      requires = [rspamdSocket];
    };

    users.extraUsers.${postfixCfg.user}.extraGroups = [rspamdCfg.group];
  };
}