{
  config,
  pkgs,
  lib,
  ...
}: let
  inherit (lib.modules) mkIf;
  inherit (lib.attrsets) mapAttrsToList;
  inherit (lib.strings) concatStringsSep optionalString;

  mailConfig = config.services.mailserver;
  vmailConfig = mailConfig.vmail;

  postfixCfg = config.services.postfix;

  dovecotRuntimeDir = "/run/dovecot2";
  passwdFile = "${dovecotRuntimeDir}/passwd";

  genPasswdScript = pkgs.writeScript "generate-password-file" ''
    #!${pkgs.stdenv.shell}

    set -euo pipefail

    ${concatStringsSep "\n" (map (userPasswdFile: ''
      if [ ! -f "${userPasswdFile}" ]; then
        echo "Expected password hash file ${userPasswdFile} does not exist!"
        exit 1
      fi
    '') (mapAttrsToList (_email: config: config.passwordHashFile) mailConfig.accounts))}

    cat <<EOF > ${passwdFile}
    ${concatStringsSep "\n" (mapAttrsToList (
        email: config: "${email}:$(head -n 1 ${config.passwordHashFile})"
      )
      mailConfig.accounts)}
    EOF
  '';
in {
  config = mkIf mailConfig.enable {
    services.dovecot2 = {
      enable = true;
      enableImap = true;
      enableLmtp = true;
      enableQuota = true;
      enablePop3 = false;
      enablePAM = false; # Not using PAM for Auth

      mailUser = vmailConfig.user;
      mailGroup = vmailConfig.group;
      mailLocation = "maildir:${vmailConfig.directory}/%d/%n";

      sslServerCert = mailConfig.sslConfig.cert;
      sslServerKey = mailConfig.sslConfig.key;

      # For Sieve
      modules = with pkgs; [
        dovecot_pigeonhole
      ];
      protocols = ["sieve"];

      mailboxes = {
        Trash = {
          auto = "no";
          specialUse = "Trash";
        };
        Junk = {
          auto = "subscribe";
          specialUse = "Junk";
        };
        Drafts = {
          auto = "subscribe";
          specialUse = "Drafts";
        };
        Sent = {
          auto = "subscribe";
          specialUse = "Sent";
        };
      };

      extraConfig = ''
        ${optionalString mailConfig.debugMode ''
          mail_debug = yes
          auth_debug = yes
          verbose_ssl = yes
        ''}

        service imap-login {
            inet_listener imap {
              port = 143
            }
            inet_listener imaps {
                port = 993
                ssl = yes
            }
        }

        protocol imap {
            mail_max_userip_connections = 100
            mail_plugins = $mail_plugins imap_sieve
        }

        ssl = required
        ssl_min_protocol = TLSv1.2
        ssl_prefer_server_ciphers = yes

        service lmtp {
            unix_listener dovecot-lmtp {
                group = ${postfixCfg.group}
                mode = 0600
                user = ${postfixCfg.user}
            }
        }

        recipient_delimiter = "+"
        lmtp_save_to_detail_mailbox = "no"

        protocol lmtp {
            mail_plugins = $mail_plugins sieve
        }

        mail_access_groups = "${vmailConfig.group}"

        userdb {
            driver = static
            args = uid=${toString vmailConfig.userID} gid=${toString vmailConfig.groupID}
        }

        passdb {
            driver = passwd-file
            args = ${passwdFile}
        }

        service auth {
            unix_listener auth {
                mode = 0660
                user = ${postfixCfg.user}
                group = ${postfixCfg.group}
            }
        }

        auth_mechanisms = plain login

        namespace inbox {
          separator = "."
          inbox = yes
        }

        plugin {
            sieve_plugins = sieve_imapsieve sieve_extprograms
            sieve = file:${mailConfig.sieveDirectory}/%u/scripts;active=${mailConfig.sieveDirectory}/%u/active.sieve
            sieve_default = file:${mailConfig.sieveDirectory}/%u/default.sieve
            sieve_default_name = default
            sieve_global_extensions = +vnd.dovecot.environment
        }
        lda_mailbox_autosubscribe = yes
        lda_mailbox_autocreate = yes
      '';
    };

    systemd = {
      tmpfiles.rules = [
        "f ${passwdFile} 600 dovecot2 dovecot2"
      ];
      services = {
        dovecot2.preStart = ''
          ${genPasswdScript}
        '';
        postfix.restartTriggers = [genPasswdScript];
      };
    };
  };
}