{
  config,
  lib,
  ...
}: let
  inherit (lib) types;
  inherit (lib.options) mkEnableOption mkOption;

  cfg = config.services.mailserver;
in {
  options.services.mailserver = {
    enable = mkEnableOption "mailserver";

    fqdn = mkOption {
      type = types.str;
      description = "domain used for mx records";
    };

    domains = mkOption {
      type = types.listOf types.str;
      description = "all domains for receiving mail on";
    };

    debugMode = mkOption {
      type = types.bool;
      default = false;
      description = "enable debug logging on everything";
    };

    sslConfig = {
      useACME = mkOption {
        type = types.bool;
        default = true;
      };
      cert = mkOption {
        type = types.str;
        default = "/var/lib/acme/${cfg.fqdn}/fullchain.pem";
      };
      key = mkOption {
        type = types.str;
        default = "/var/lib/acme/${cfg.fqdn}/key.pem";
      };
    };

    spf = {
      enable = mkOption {
        type = types.bool;
        default = true;
      };
      policydConfig = mkOption {
        type = types.str;
        default = "";
      };
    };

    accounts = mkOption {
      # where attrName = email for login
      default = {};
      type = types.attrsOf (types.submodule {
        options = {
          passwordHashFile = mkOption {
            type = types.str;
            description = ''
              a file containing the hashed password for user, loaded at runtime

            '';
          };
          aliases = mkOption {
            type = types.listOf types.str;
            default = [];
            description = "a list of aliases for receiving/sending mail";
          };
          sieveScript = mkOption {
            type = types.nullOr types.lines;
            default = null;
            description = "a default sieve script for filtering mail";
          };
        };
      });
    };

    extraAliasesFile = mkOption {
      type = types.nullOr types.str;
      default = null;
      description = "file containing postfix aliases for receiving, loaded at runtime";
    };

    sieveDirectory = mkOption {
      type = types.str;
      default = "/var/sieve";
      description = "path used for storing sieve scripts";
    };

    dkim = {
      enable = mkOption {
        type = types.bool;
        default = true;
      };
      directory = mkOption {
        type = types.str;
        default = "/var/dkim";
        description = "path used for storing dkim signing keys, make sure to keep this backed up";
      };
    };

    vmail = {
      user = mkOption {
        type = types.str;
        default = "vmail";
      };
      group = mkOption {
        type = types.str;
        default = "${cfg.vmail.user}";
      };
      userID = mkOption {
        type = types.number;
        default = 5000;
      };
      groupID = mkOption {
        type = types.number;
        default = cfg.vmail.userID;
      };
      directory = mkOption {
        type = types.str;
        default = "/home/${cfg.vmail.user}";
      };
    };
  };
}
