#
# System notifications
#

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

let
  fqdn = "matrix.${config.networking.domain}";
  clientConfig = {
    "m.homeserver".base_url = "https://${fqdn}";
    "m.identity_server" = {};
  };
  serverConfig."m.server" = "${fqdn}:443";
  mkWellKnown = data: ''
    add_header Content-Type application/json;
    add_header Access-Control-Allow-Origin *;
    return 200 '${builtins.toJSON data}';
  '';
in {
  environment.systemPackages = [
    pkgs.mautrix-whatsapp
    pkgs.signald
    pkgs.mautrix-signal
  ];

  services.nginx = {
    enable = true;
    recommendedTlsSettings = true;
    recommendedOptimisation = true;
    recommendedGzipSettings = true;
    recommendedProxySettings = true;
    virtualHosts = {
      "${config.networking.domain}" = { 
        enableACME = true;
        forceSSL = true;
        locations."= /.well-known/matrix/server".extraConfig = mkWellKnown serverConfig; 
        locations."= /.well-known/matrix/client".extraConfig = mkWellKnown clientConfig; 
        locations."/_matrix".proxyPass = "http://localhost:8008"; 
      };
      "${fqdn}" = {
        enableACME = true;
        forceSSL = true;
        locations."/health".proxyPass = "http://localhost:8008"; 
        locations."/_matrix".proxyPass = "http://localhost:8008"; 
        locations."/_synapse/client".proxyPass = "http://localhost:8008"; 
        locations."/".extraConfig = '' 
          return 404;
        '';
      };
#      "element.${config.networking.domain}" = {
#        enableACME = true;
#        forceSSL = true;
#
#        root = pkgs.element-web.override {
#            conf = {
#                default_server_config = clientConfig;
#            };
#        };
#      };
    };
  };

  services.matrix-synapse = {
    enable = true;
    settings = {
        server_name = config.networking.domain;
        public_baseurl = "https://matrix.${config.networking.domain}";
        listeners = [
          { port = 8008;
            bind_addresses = [ "::1" ];
            type = "http";
            tls = false;
            x_forwarded = true;
            resources = [ 
              { names = [ "client" ]; compress = true; }
              { names = [ "federation" ]; compress = false; }
            ];
          }
        ];
        app_service_config_files = [
            config.age.secrets."services/matrix/whatsapp-registration.yml".path
            config.age.secrets."services/matrix/telegram-registration.yml".path
            config.age.secrets."services/matrix/signal-registration.yml".path
        ];
    };
    extraConfigFiles = [
        config.age.secrets."services/matrix/synapse.yml".path
    ];
  };

  systemd.services = {
      matrix-synapse = {
          requires = [ "postgresql.service" ];
      };
      mautrix-whatsapp = {
        description = "Matrix <-> WhatsApp bridge";
        wantedBy = [ "multi-user.target" ];
        after = [ "network.target" "postgresql.service" "matrix-synapse.service" ];
        requires = [ "postgresql.service" "matrix-synapse.service" ];
        script = "${pkgs.mautrix-whatsapp}/bin/mautrix-whatsapp -n --config ${config.age.secrets."services/matrix/mautrix-whatsapp.yml".path}";
        serviceConfig = {
          User = "mautrix-whatsapp";
          Group = "mautrix-whatsapp";
          Environment = "HOME=/var/lib/mautrix-whatsapp";
          ReadWritePaths="/var/log/mautrix-whatsapp";
          NoNewPrivileges=true;
          MemoryDenyWriteExecute=true;
          PrivateDevices=true;
          PrivateTmp=true;
          ProtectHome=true;
          ProtectSystem="strict";
          ProtectControlGroups=true;
          RestrictSUIDSGID=true;
          RestrictRealtime=true;
          LockPersonality=true;
          ProtectKernelLogs=true;
          ProtectKernelTunables=true;
          ProtectHostname=true;
          ProtectKernelModules=true;
          PrivateUsers=true;
          ProtectClock=true;
          SystemCallArchitectures="native";
          SystemCallErrorNumber="EPERM";
          SystemCallFilter="@system-service";
        };
      };
      mautrix-signal = {
        description = "Matrix <-> Signal bridge";
        wantedBy = [ "multi-user.target" ];
        after = [ "network.target" "postgresql.service" "matrix-synapse.service" "signald.service" ];
        requires = [ "postgresql.service" "matrix-synapse.service" "signald.service"];
        script = "${pkgs.mautrix-signal}/bin/mautrix-signal -n --config ${config.age.secrets."services/matrix/mautrix-signal.yml".path}";
        serviceConfig = {
          User = "mautrix-signal";
          Group = "mautrix-signal";
          Environment = "HOME=/var/lib/mautrix-signal";
          ReadWritePaths= [
            "/var/run/signald/signald.sock"
            "/var/log/mautrix-signal"
          ];
          NoNewPrivileges=true;
          MemoryDenyWriteExecute=true;
          PrivateDevices=true;
          PrivateTmp=true;
          ProtectHome=true;
          ProtectSystem="strict";
          ProtectControlGroups=true;
          RestrictSUIDSGID=true;
          RestrictRealtime=true;
          LockPersonality=true;
          ProtectKernelLogs=true;
          ProtectKernelTunables=true;
          ProtectHostname=true;
          ProtectKernelModules=true;
          PrivateUsers=true;
          ProtectClock=true;
          SystemCallArchitectures="native";
          SystemCallErrorNumber="EPERM";
          SystemCallFilter="@system-service";
        };
      };
  };
  systemd.tmpfiles.rules = [
    "d /var/log/mautrix-whatsapp - mautrix-whatsapp mautrix-whatsapp"
    "d /var/log/mautrix-signal - mautrix-signal mautrix-signal"
  ];

  users = {
    users = {
      mautrix-whatsapp = {
        uid = 3001;
        group = "mautrix-whatsapp";
        isSystemUser = true;
      };
      mautrix-telegram = {
        uid = 3002;
        group = "mautrix-telegram";
        isSystemUser = true;
      };
      mautrix-signal = {
        uid = 3003;
        group = "mautrix-signal";
        isSystemUser = true;
      };
    };
    groups = {
      mautrix-whatsapp = {
        gid = 3001;
      };
      mautrix-telegram = {
        gid = 3002;
      };
      mautrix-signal = {
        gid = 3003;
      };
    };
  };

  services = {
      mautrix-telegram = {
          enable = true;
          environmentFile = config.age.secrets."services/matrix/mautrix-telegram.env".path;
          settings = {
              homeserver = {
                  address = "http://localhost:8008";
                  domain = "kabtop.de";
              };
              appservice = {
                  hostname = "127.0.0.1";
                  port = "29317";
                  provisioning.enabled = false;
                  id = "telegram";
                  public = {
                      enabled = false;
                  };
              };
              bridge = {
                  sync_channel_members = true;
                  startup_sync = true;
                  public_portals = true;
                  double_puppet_server_map = {
                    "kabtop.de" = "https://kabtop.de";
                  };
                  encryption = {
                      allow = true;
                      default = true;
                      verification_levels = {
                          receive = "cross-signed-untrusted";
                          send = "cross-signed-untrusted";
                      };
                  };
                  private_chat_portal_meta = "default";
                  backfill = {
                      disable_notifications = true;
                  };
                  permissions = {
                      "@kabbone:kabtop.de" = "admin";
                  };
              };
              logging = {
                  loggers = {
                    mau = {
                      level = "WARN";
                    };
                    telethon = {
                      level = "WARN";
                    };
                  };
                  root = {
                    handlers = [
                      "console"
                    ];
                    level = "WARN";
                  };
              };
          };
      };
      signald = {
        enable = true;
        user = "mautrix-signal";
        group = "mautrix-signal";
      };
  };

  age.secrets."services/matrix/synapse.yml" = {
     file = ../../../secrets/services/matrix/synapse.age;
     owner = "matrix-synapse";
  };
  age.secrets."services/matrix/mautrix-telegram.env" = {
     file = ../../../secrets/services/matrix/mautrix-telegram.age;
     owner = "mautrix-telegram";
  };
  age.secrets."services/matrix/mautrix-whatsapp.yml" = {
     file = ../../../secrets/services/matrix/mautrix-whatsapp.age;
     owner = "mautrix-whatsapp";
  };
  age.secrets."services/matrix/mautrix-signal.yml" = {
     file = ../../../secrets/services/matrix/mautrix-signal.age;
     owner = "mautrix-signal";
  };
  age.secrets."services/matrix/telegram-registration.yml" = {
     file = ../../../secrets/services/matrix/telegram-registration.age;
     owner = "matrix-synapse";
  };
  age.secrets."services/matrix/whatsapp-registration.yml" = {
     file = ../../../secrets/services/matrix/whatsapp-registration.age;
     owner = "matrix-synapse";
  };
  age.secrets."services/matrix/signal-registration.yml" = {
     file = ../../../secrets/services/matrix/signal-registration.age;
     owner = "matrix-synapse";
  };

}