{ pkgs, lib, config, inputs, hostName, ... }:
let
  inherit (lib) types;
  inherit (config.services) postfix rspamd dovecot2;
  redis = config.services.redis.servers.rspamd;
  inherit (config.users) users groups;
in
{
  imports = [
    rspamd/autogeree.net.nix
    rspamd/sourcephile.fr.nix
  ];
  options = {
    services.rspamd.dkimSelectorMap = lib.mkOption {
      type = types.lines;
      default = "";
      description = ''Each line maps a domain to its active DKIM selector'';
      apply = s: pkgs.writeText "dkim_selectors.map" s;
    };
  };
  config = {
    users.groups.redis-rspamd.members = [ rspamd.user ];
    services.rspamd = {
      enable = true;
      debug = false;
      postfix.enable = postfix.enable;
      locals = {
        "dkim_signing.conf".text = ''
          selector_map = ${rspamd.dkimSelectorMap};
          path = "/run/credentials/rspamd.service/$domain.$selector.key";
          allow_username_mismatch = true;
        '';
        "arc.conf".text = ''
          selector_map = ${rspamd.dkimSelectorMap};
          path = "/run/credentials/rspamd.service/$domain.$selector.key";
          allow_username_mismatch = true;
        '';
        "redis.conf".text = ''
          servers = "${redis.unixSocket}";
          db = "1";
        '';
        "classifier-bayes.conf".text = ''
          users_enabled = false;
          backend = "redis";
          servers = "${redis.unixSocket}";
          database = "1";
          autolearn = true;
          cache {
            backend = "redis";
          }
          new_schema = true;
          expire = 86400;
          statfile {
            BAYES_HAM {
              spam = false;
            }
            BAYES_SPAM {
              spam = true;
            }
          }
        '';
        /*
          "logging.conf" = ''
      debug_modules = [“dkim_signing”]
          '';
        */
      };
      overrides = {
        "milter_headers.conf".text = ''
          extended_spam_headers = true;
        '';
        "actions.conf".text = ''
          reject     = 15; # Reject when reaching this score
          add_header =  6; # Add header when reaching this score
          greylist   =  4; # Apply greylisting when reaching this score (will emit `soft reject action`)
        '';
      };
      workers = {
        learner = {
          # Like controller but without a password, only the bindSockets' permissions
          type = "controller";
          includes = [ "$CONFDIR/worker-controller.inc" ];
          bindSockets = [
            {
              socket = "/run/rspamd/learner.sock";
              mode = "0660";
              owner = "${rspamd.user}";
              group = "${dovecot2.group}";
            }
          ];
          extraConfig = ''
      '';
        };
        controller = {
          includes = [
            "$CONFDIR/worker-controller.inc"
            "/run/credentials/rspamd.service/controller.inc"
          ];
          bindSockets = [
            "127.0.0.1:11334"
          ];
          extraConfig = ''
            #count = 1;
            #static_dir = "''${WWWDIR}";
          '';
        };
      };
    };
    systemd.services.rspamd = {
      serviceConfig = {
        LoadCredentialEncrypted = [
          "controller.inc:${inputs.self}/hosts/${hostName}/rspamd/controller.inc.cred"
        ];
      };
    };

    fileSystems."/var/lib/redis-rspamd" = {
      device = "rpool/var/redis-rspamd";
      fsType = "zfs";
    };
    services.sanoid.datasets."rpool/var/redis-rspamd" = {
      use_template = [ "snap" ];
      daily = 7;
      monthly = 0;
    };

    services.redis.vmOverCommit = true;
    services.redis.servers.rspamd = {
      enable = true;
      databases = 16;
      syslog = true;
      save = [ [ 1800 100 ] [ 300 1000 ] ];
      #unixSocketPerm = "660";
      settings = {
        maxmemory = "64MB";
        maxmemory-policy = "volatile-ttl";
      };
    };
    /*
      services.postfix.extraConfig = ''
      smtpd_milters = unix:/run/rspamd.sock
      milter_default_action = accept
      '';
      # Allow users to run 'rspamc' and 'rspamadm'.
      environment.systemPackages = [ pkgs.rspamd ];
    */
  };
}