{
  config,
  lib,
  ...
}: let
  cfg = config.services.lldap;
in {
  imports = [
    ./bootstrap/lldap-bootstrap.nix
  ];

  sops.secrets = {
    "lldap/jwt_secret".owner = "lldap";
    "lldap/key_seed".owner = "lldap";
    "lldap/admin_password".owner = "lldap";
  };

  sops.templates."lldap_config.toml".content = ''
    LLDAP_SMTP_OPTIONS__PASSWORD=${config.sops.placeholder."lldap/admin_password"}
  '';

  networking.firewall.allowedTCPPorts = [
    cfg.settings.http_port
    cfg.settings.ldap_port
  ];

  services.lldapBootstrap.enable = true;

  services.lldap = {
    enable = true;
    settings = {
      verbose = true;
      ldap_base_dn = "dc=procopius,dc=dk";
      ldap_user_email = "admin@procopius.dk";
      http_url = "https://lldap.procopius.dk";
      enable_password_reset = true;

      database_url = "postgresql://lldap@localhost/lldap?host=/run/postgresql";
    };
    environment = {
      LLDAP_JWT_SECRET_FILE = config.sops.secrets."lldap/jwt_secret".path;
      LLDAP_KEY_SEED_FILE = config.sops.secrets."lldap/key_seed".path;
      LLDAP_LDAP_USER_PASS_FILE = config.sops.secrets."lldap/admin_password".path;

      LLDAP_SMTP_OPTIONS__ENABLE_PASSWORD_RESET = "true";
      LLDAP_SMTP_OPTIONS__SERVER = "mail.procopius.dk";
      LLDAP_SMTP_OPTIONS__PORT = "465";
      LLDAP_SMTP_OPTIONS__SMTP_ENCRYPTION = "TLS";
      LLDAP_SMTP_OPTIONS__USER = "admin@procopius.dk";
      LLDAP_SMTP_OPTIONS__FROM = "LLDAP Admin <admin@procopius.dk>";
      LLDAP_SMTP_OPTIONS__REPLY_TO = "Do not reply <noreply@procopius.dk>";
    };
    environmentFile = config.sops.templates."lldap_config.toml".path;
  };

  systemd.services.lldap = let
    dependencies = [
      "postgresql.service"
    ];
  in {
    # LLDAP requires PostgreSQL to be running
    after = dependencies;
    requires = dependencies;
    # DynamicUser screws up sops-nix ownership because
    # the user doesn't exist outside of runtime.
    serviceConfig.DynamicUser = lib.mkForce false;
  };

  # Setup a user and group for LLDAP
  users = {
    users.lldap = {
      group = "lldap";
      isSystemUser = true;
    };
    groups.lldap = {};
  };
}
