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

let
  domain = "runas.rocks";
  db_name = "matrix-synapse-runas.rocks";

  utilities = import ./utilities.nix { inherit lib config; };
  inherit (utilities) architectInterfaceAddress;
in
{
  services = {
    matrix-synapse = {
      enable = true;
      settings = {
        server_name = "${domain}";
        database.args.database = db_name;
        public_baseurl = "https://${domain}";
        registration_shared_secret = "runas!";
        url_preview_enabled = true;
        dynamic_thumbnails = true;
        withJemalloc = true;
        enable_registration = false;
        password_config.enabled = true;

        auto_join_rooms = [ "#general:${domain}" "#music:${domain}" "#movies:${domain}" ];

        listeners = [{
          port = 8008;
          bind_addresses = [ "127.0.0.1" ];
          type = "http";
          tls = false;
          x_forwarded = true;
          resources = [{
            names = [ "client" "federation" ];
            compress = false;
          }];
        }];
      };
    };

    postgresql = {
      enable = true;
      package = pkgs.postgresql;
      # ensureUsers = [{
      #   name = db_name;
      #   ensurePermissions = { "DATABASE \"${db_name}\"" = "ALL PRIVILEGES"; };
      # }];
    };

    nginx.virtualHosts = {
      # server
      ${domain} = {
        enableACME = true;
        forceSSL = true;
        extraConfig = ''
          client_max_body_size  30m;
        '';
        locations."= /.well-known/matrix/server".extraConfig =
          let server = { "m.server" = "${domain}:443"; };
          in
          ''
            add_header Content-Type application/json;
            return 200 '${builtins.toJSON server}';
          '';

        locations."= /.well-known/matrix/client".extraConfig =
          let
            client = {
              "m.homeserver" = { "base_url" = "https://${domain}:443"; };
              "m.identity_server" = { "base_url" = "https://vector.im"; };
            };
            # ACAO required to allow element-web on any URL to request this json file
          in
          ''
            add_header Content-Type application/json;
            add_header Access-Control-Allow-Origin *;
            return 200 '${builtins.toJSON client}';
          '';

        #        locations."/".extraConfig = ''
        #          return 404;
        #        '';

        # forward all Matrix API calls to the synapse Matrix homeserver
        locations."/_matrix" = {
          proxyPass = "http://127.0.0.1:8008"; # without a trailing /
        };

        locations."/_synapse" = {
          proxyPass = "http://127.0.0.1:8008"; # without a trailing /
        };
      };
    };
  };

  networking.extraHosts = ''
    ${architectInterfaceAddress "lan"} ${domain}
    ${architectInterfaceAddress "tailscale"} ${domain}
  '';
}