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

with pkgs;

# NOTE Reference the environment variable set in the corresponding agenix secret
let
  database = {
    connection_string = "$DB_STRING";
    max_open_conns = 100;
    max_idle_conns = 5;
    conn_max_lifetime = -1;
  };

in
{
  # Matrix server configuration
  services.dendrite = {
    enable = true;
    httpPort = 8008;
    environmentFile = config.age.secrets.dendrite-postgres.path;
    loadCredential = [ "private_key:${config.age.secrets.dendrite.path}" ];
    settings = {
      global = {
        server_name = "coolneng.duckdns.org";
        private_key = config.age.secrets.dendrite.path;
        inherit database;
        dns_cache.enabled = true;
      };
      # HACK Inherit postgres connection string for the rest of the DBs
      app_service_api = {
        inherit database;
        config_files = [
          "/var/lib/matrix-as-facebook/facebook-registration.yaml"
          "/var/lib/matrix-as-signal/signal-registration.yaml"
          "/var/lib/matrix-as-telegram/telegram-registration.yaml"
        ];
      };
      media_api = {
        inherit database;
      };
      room_server = {
        inherit database;
      };
      push_server = {
        inherit database;
      };
      mscs = {
        inherit database;
        mscs = [
          "msc2836"
          "msc2946"
        ];
      };
      sync_api = {
        inherit database;
      };
      key_server = {
        inherit database;
      };
      federation_api = {
        inherit database;
      };
      user_api = {
        account_database = database;
        device_database = database;
      };
    };
  };

  # Start dendrite after config files are mounted
  systemd.services.dendrite.unitConfig.RequiresMountsFor = [
    /var/lib/matrix-as-facebook
    /var/lib/matrix-as-signal
    /var/lib/matrix-as-telegram
  ];

  # Matrix bridges
  services.matrix-appservices = {
    homeserver = "dendrite";
    homeserverDomain = "coolneng.duckdns.org";
    homeserverURL = "https://matrix.coolneng.duckdns.org";
    services = {
      telegram = {
        port = 8118;
        format = "mautrix-python";
        package = mautrix-telegram;
        serviceConfig.EnvironmentFile = config.age.secrets.telegram.path;
        settings = {
          appservice.database = "$DB_STRING";
          homeserver.software = "standard";
          telegram = {
            api_id = "$API_ID";
            api_hash = "$API_HASH";
          };
          bridge = {
            permissions."@coolneng:coolneng.duckdns.org" = "admin";
            backfill.normal_groups = true;
          };
        };
      };
      facebook = {
        port = 8228;
        format = "mautrix-python";
        package = mautrix-meta;
        serviceConfig.EnvironmentFile = config.age.secrets.facebook.path;
        settings = {
          appservice.database = "$DB_STRING";
          homeserver.software = "standard";
          bridge.permissions."@coolneng:coolneng.duckdns.org" = "admin";
        };
      };
    };
  };

  # Enable voice messages for facebook
  systemd.services.matrix-as-facebook.path = [ ffmpeg ];

  # MQTT configuration
  services.mosquitto = {
    enable = true;
    dataDir = "/vault/mosquitto";
    logType = [
      "websockets"
      "error"
      "warning"
      "notice"
      "information"
    ];
    logDest = [ "syslog" ];
    listeners = [
      {
        users.homeostasis = {
          acl = [ "write #" ];
          hashedPasswordFile = config.age.secrets.mqtt-sender.path;
        };
        users.prometheus = {
          acl = [ "read #" ];
          hashedPasswordFile = config.age.secrets.mqtt-receiver.path;
        };
      }
    ];
  };

}