{ config, pkgs, lib, ... }:

let
  domain = "mailtngbert.c3d2.de";

  ldap-auth-config = pkgs.writeText "ldap-auth-settings" ''
    uris = ldaps://auth.c3d2.de
    dn = uid=search,ou=users,dc=c3d2,dc=de
    !include ${config.sops.secrets."ldap/search-user-pw".path}

    auth_bind = yes
    auth_bind_userdn = uid=%n,ou=users,dc=c3d2,dc=de
    ldap_version = 3
    base = ou=users,dc=c3d2,dc=de
    scope = subtree
    user_attrs = homeDirectory=home,uidNumber=uid,gidNumber=gid

    user_filter = (&(objectClass=person)(uid=%n))
    pass_filter = (&(objectClass=person)(uid=%n))
  '';

in
{
  microvm.mem = 2048;

  networking = {
    hostName = "mailtngbert";
    firewall.allowedTCPPorts = [
      # postfix (smtp and submission)
      25 587
      # dovecot (imap)
      143
      # managesieve
      4190
    ];
  };

  c3d2 = {
    deployment.server = "server10";
    hq.statistics.enable = true;
  };

  sops.defaultSopsFile = ./secrets.yaml;
  sops.secrets."ldap/search-user-pw" = {
    owner = config.users.users.dovecot2.name;
    inherit (config.users.users.dovecot2) group;
  };

  services = {
    portunus.addToHosts = true;
    postfix = {
      enable = true;
      enableSmtp = true;
      enableSubmission = true;
      enableHeaderChecks = true;
      domain = "${domain}";
      hostname = "${domain}";
      sslCert = "/var/lib/acme/${domain}/fullchain.pem";
      sslKey = "/var/lib/acme/${domain}/key.pem";
      networks = [
        "127.0.0.1"
        "172.20.77.10" #TODO: take ip directly from server10 config
        "[2a00:8180:2c00:284::]/64"
      ];
      virtual = ''
        postmaster                                root
        abuse                                     root
        root                                      root
        garbage                                   root
      '';
        #TODO: where does root get received?
      config = {
        myorigin = "${domain}";
        mydestination = [
          "127.0.0.1"
        ];
        mail_owner = "postfix";
        smtp_use_tls = true;
        smtp_tls_security_level = "encrypt";
        smtpd_use_tls = true;
        smtpd_tls_security_level = lib.mkForce "encrypt";
        smtpd_recipient_restrictions = [
          "permit_mynetworks"
          "permit_sasl_authenticated"
          "reject_unauth_destination"
        ];
        smtpd_relay_restrictions = [
          "permit_mynetworks"
          "permit_sasl_authenticated"
          "reject_unauth_destination"
        ];
        smtpd_sasl_auth_enable = true;
        smtpd_tls_auth_only = true;
        smtpd_tls_protocols = [
          "!SSLv2"
          "!SSLv3"
          "!TLSv1"
          "!TLSv1.1"
        ];
        smtpd_tls_mandatory_ciphers = "high";
        smtpd_sasl_path = "/var/lib/postfix/auth";
        smtpd_sasl_type = "dovecot";
        virtual_mailbox_domains = [
          "${domain}"
        ];
        virtual_gid_maps = "static:5000";
        virtual_uid_maps = "static:5000";
        virtual_minimum_uid = "1000";
        virtual_transport = "lmtp:unix:/run/dovecot2/dovecot-lmtp";
        virtual_mailbox_base = "/var/spool/mail";
        message_size_limit = "40960000";
      };
    };
    dovecot2 = {
      enable = true;
      enableImap = true;
      enableLmtp = true;
      enablePop3 = false;
      enablePAM = false;
      enableQuota = true;
      createMailUser = true;
      mailLocation = "maildir:/var/mail/%u";
      mailboxes = {
        Spam = {
          auto = "create";
          specialUse = "Junk";
        };
        Sent = {
          auto = "create";
          specialUse = "Sent";
        };
        Drafts = {
          auto = "create";
          specialUse = "Drafts";
        };
        Trash = {
          auto = "create";
          specialUse = "Trash";
        };
      };
      modules = [
        pkgs.dovecot_pigeonhole
      ];
      quotaGlobalPerUser = "1G";
      sslServerCert = "/var/lib/acme/${domain}/fullchain.pem";
      sslServerKey = "/var/lib/acme/${domain}/key.pem";
      protocols = [ ];
      mailPlugins = {
        perProtocol = {
          imap = {
            enable = [ ];
          };
          lmtp = {
            enable = [ ];
          };
        };
      };
      extraConfig = ''
        passdb {
          driver = ldap
          args = ${ldap-auth-config}
        }
        userdb {
          driver = ldap
          args = ${ldap-auth-config}
        }
        service lmtp {
         unix_listener dovecot-lmtp {
           group = postfix
           mode = 0660
           user = postfix
          }
        }
        service auth {
          unix_listener /var/lib/postfix/auth {
            group = postfix
            mode = 0660
            user = postfix
          }
          user = dovecot2
        }

        protocol lmtp {
          postmaster_address = root@c3d2.de
        }

        protocol imap {
          mail_max_userip_connections = 100
        }
        mail_uid = ${config.users.users.dovecot2.name}
        mail_gid = ${config.users.users.dovecot2.group}
        first_valid_uid = ${toString config.users.users.dovecot2.uid}
      '';
    };
    nginx = {
      enable = true;
      virtualHosts."${domain}" = {
        forceSSL = true;
        enableACME = true;
        /*
        locations."/rspamd/" = {
          proxyPass = "http://127.0.0.1:11334/";
          extraConfig = ''
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          '';
        };
        */
      };
    };
  };

  security.acme.certs."${domain}" = {
    reloadServices = [
      "postfix.service"
      "dovecot2.service"
    ];
  };

  system.stateVersion = "22.11";
}
