{ config, ... }:
let
  cfg = config.machine.synapse;

  clientConfig."m.homeserver".base_url = "https://${cfg.domain}";
  serverConfig."m.server" = "${cfg.domain}:443";
  mkWellKnown = data: ''
    default_type application/json;
    add_header Access-Control-Allow-Origin *;
    return 200 '${builtins.toJSON data}';
  '';
in
{
  systemd.services.nginx.serviceConfig.SupplementaryGroups = [ "matrix-synapse" ];

  services.nginx = {
    appendHttpConfig = ''
      limit_req_zone $binary_remote_addr zone=matrix:10m rate=50r/s;
    '';
    virtualHosts.${cfg.domain} = {
      forceSSL = true;
      enableACME = true;

      locations = {
        "= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig;
        "= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig;
        "^~ /_matrix" = {
          proxyPass = "http://127.0.0.1:${toString cfg.port}";
          extraConfig = ''
            limit_req zone=matrix burst=100 nodelay;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_read_timeout 600s;
            proxy_connect_timeout 60s;
            proxy_send_timeout 600s;
            client_max_body_size 50M;
          '';
        };

        # Health check
        "= /health" = {
          proxyPass = "http://127.0.0.1:${toString cfg.port}";
          extraConfig = ''
            access_log off;
          '';
        };

        # Block admin API from public
        "/_synapse/admin".return = "404";
      };
    };
  };
}
