{ config, lib, pkgs, ... }:
{
  c3d2.deployment.server = "server10";

  microvm = {
    mem = 1024;
    vcpu = 2;
  };

  networking.hostName = "mobilizon";

  services = {
    mobilizon = {
      enable = true;
      settings = let
        # copied from nixos/modules/services/web-apps/mobilizon.nix
        settingsFormat = pkgs.formats.elixirConf { elixir = pkgs.elixir_1_14; };
      in {
        ":mobilizon" = {
          ":instance" = {
            default_language = "de";
            email_from = "mobilizon@c3d2.de";
            email_reply_to = "noreply@c3d2.de";
            name = "C3D2 Mobilizon";
            hostname = "mobilizon.c3d2.de";
            registrations_open = false;
            # registration_email_allowlist = [ "c3d2.de" ]; # we use ldpa login instead :)
          };
          # TODO: move to nixos-modules
          ":ldap" = let
            inherit (config.security) ldap;
          in {
            enabled = true;
            base = ldap.userBaseDN;
            bind_uid = { value = ''{:full, "uid=search,ou=users,dc=c3d2,dc=de"}''; _elixirType = "raw"; };
            bind_password = settingsFormat.lib.mkGetEnv { envVariable = "MOBILIZON_LDAP_BIND_PASSWORD"; };
            group = "cn=mobilizon-users,ou=groups,dc=c3d2,dc=de";
            host = ldap.domainName;
            port = ldap.port;
            require_bind_for_search = true;
            ssl = true;
            sslopts = [ { cacertfile = "/etc/ssl/certs/ca-certificates.crt"; } ];
            uid = ldap.userField;
          };
          ":logger" = {
            # level = { value = ":notice"; _elixirType = "atom"; };
            level = { value = ":debug"; _elixirType = "atom"; };
          };
          "Mobilizon.Service.Auth.Authenticator" = { value = "Mobilizon.Service.Auth.LDAPAuthenticator"; _elixirType = "raw"; };
          # https://docs.joinmobilizon.org/administration/configure/geocoders/#photon
          # TOS: You can use the API for your project, but please be fair - extensive usage will be throttled. We do not guarantee for the availability and usage might be subject of change in the future.
          "Mobilizon.Service.Geospatial.Photon".endpoint = "https://photon.komoot.io";
          "Mobilizon.Web.Endpoint" = {
            has_reverse_proxy = true;
            url = {
              host = "mobilizon.c3d2.de";
              scheme = "https";
            };
          };
          "Mobilizon.Web.Email.Mailer" = {
            adapter = { value = "Bamboo.SMTPAdapter"; _elixirType = "raw"; };
            server = "mail.c3d2.de";
            hostname = config.networking.hostName;
            auth = false;
            port = 587;
            ssl = false;
            tls = { value = ":if_available"; _elixirType = "atom"; };
            allowed_tls_versions = { value = ''[:"tlsv1.1", :"tlsv1.2"]''; _elixirType = "raw"; };
            retries = 1;
            no_mx_lookups = true;
          };
        };
        ":web_push_encryption".":vapid_details" = {
          private_key = settingsFormat.lib.mkGetEnv { envVariable = "MOBILIZON_VAPID_PRIVAT_KEY"; };
          public_key = settingsFormat.lib.mkGetEnv { envVariable = "MOBILIZON_VAPID_PUBLIC_KEY"; };
          subject = "mailto:mail@c3d2.de";
        };
      };
    };

    nginx = {
      enable = true;
      virtualHosts."mobilizon.c3d2.de" = {
        default = true;
        forceSSL = true;
        enableACME = true;
      };
    };

    portunus.addToHosts = true;

    postgresql = {
      package = pkgs.postgresql_16;
      upgrade.stopServices = [ "mobilizon" ];
    };
  };

  sops = {
    defaultSopsFile = ./secrets.yaml;
    secrets = {
      "mobilizon/environment" = { };
      "restic/password".owner = "root";
      "restic/repositories/server8".owner = "root";
    };
  };

  systemd = {
    services = {
      mobilizon.serviceConfig = {
        EnvironmentFile = config.sops.secrets."mobilizon/environment".path;
        TimeoutStartSec = 300; # default of 90s timed out when doing upgrade migrations from 3.1.4 to 3.2.0
      };

      mobilizon-download-geoip = {
        description = "Download GeoIP DB for mobilizon";
        # https://framagit.org/framasoft/mobilizon/-/blob/main/docker/tests/Dockerfile#L11
        script = ''
          mkdir -p /var/lib/mobilizon/geo/
          ${lib.getExe pkgs.curl} -s https://dbip.mirror.framasoft.org/files/dbip-city-lite-latest.mmdb --output /var/lib/mobilizon/geo/GeoLite2-City.mmdb
        '';
        wantedBy = [ "timers.target" ];
      };
    };

    timers.mobilizon-download-geoip = {
      timerConfig = {
        OnCalendar = "daily";
        Peristent = true;
      };
      wantedBy = [ "timers.target" ];
    };
  };

  system.stateVersion = "22.05";
}
