{ config, ... }:

{
  imports = [
    ./acme.nix
    ./coturn.nix
    ./matrix-appservice-irc.nix
    ./nginx.nix
  ];

  age.secrets = {
    ldap_synapse_password = {
      file = ../../secrets/neo/ldap_synapse_password.age;
      owner = "matrix-synapse";
    };

    database_extra_config = {
      file = ../../secrets/neo/database_extra_config.age;
      owner = "matrix-synapse";
    };

    note_oidc_extra_config = {
      file = ../../secrets/neo/note_oidc_extra_config.age;
      owner = "matrix-synapse";
    };

    appservice_irc_db_env = {
      file = ../../secrets/neo/appservice_irc_db_env.age;
    };

    coturn_auth_secret = {
      file = ../../secrets/neo/coturn_auth_secret.age;
      owner = "turnserver";
    };
  };

  networking.firewall = {
    allowedTCPPorts = [
      80
      443
      8008
      8448
    ];
  };

  services.matrix-synapse = {
    enable = true;

    plugins = with config.services.matrix-synapse.package.plugins; [
      matrix-synapse-ldap3
    ];

    settings = {
      server_name = "crans.org";

      report_stats = false;

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

      database = {
        name = "psycopg2";
        args = {
          user = "synapse";
          database = "synapse";
          # Password is declared in extra config
          host = "172.16.10.1";
          cp_min = 5;
          cp_max = 10;
        };
      };

      modules = [
        {
          module = "ldap_auth_provider.LdapAuthProviderModule";
          config = {
            enabled = true;
            uri = "ldap://172.16.10.157:389";
            start_tls = false;
            base = "cn=Utilisateurs,dc=crans,dc=org";
            attributes = {
              uid = "uid";
              mail = "mail";
              name = "sn";
            };
            bind_dn = "cn=synapse,ou=service-users,dc=crans,dc=org";
            bind_password_file = config.age.secrets.ldap_synapse_password.path;
            filter = "(&(objectclass=inetOrgPerson)(objectclass=posixAccount))";
          };
        }
      ];

      turn_uris = [
        "turn:${config.services.coturn.realm}:3478?transport=udp"
        "turn:${config.services.coturn.realm}:3478?transport=tcp"
      ];
      turn_shared_secret = config.age.secrets.coturn_auth_secret.path;
      turn_user_lifetime = "1h";

      app_service_config_files = [
        "/var/lib/matrix-appservice-irc/registration.yml"
      ];
    };

    extraConfigFiles = [
      config.age.secrets.database_extra_config.path
      config.age.secrets.note_oidc_extra_config.path
    ];
  };

  services.nginx.virtualHosts."matrix.crans.org" = {
    enableACME = true;
    forceSSL = true;

    listen = [
      {
        addr = "0.0.0.0";
        port = 80;
        ssl = false;
      }
      {
        addr = "[::]";
        port = 80;
        ssl = false;
      }
      {
        addr = "0.0.0.0";
        port = 443;
        ssl = true;
      }
      {
        addr = "[::]";
        port = 443;
        ssl = true;
      }
      {
        addr = "0.0.0.0";
        port = 8448;
        ssl = true;
      }
      {
        addr = "[::]";
        port = 8448;
        ssl = true;
      }
    ];

    locations."/_matrix" = {
      proxyPass = "http://localhost:8008";
      extraConfig = ''
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
      '';
    };

    locations."/_synapse/client" = {
      proxyPass = "http://localhost:8008";
      extraConfig = ''
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
      '';
    };

    locations."/_synapse/admin" = {
      proxyPass = "http://localhost:8008";
      extraConfig = ''
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
      '';
    };
  };
}