{ pkgs, lib, config, hosts, ... }:
let
  inherit (config.services) prosody;
  inherit (hosts.mermet.config.services) coturn;
  domain = config.networking.domain;
in
{
  imports = [
    prosody/biboumi.nix
  ];
  networking.nftables.ruleset = ''
    table inet filter {
      chain input-net {
        tcp dport { xmpp-client, xmpp-server } counter accept comment "prosody: XMPP"
        tcp dport 5000 counter accept comment "prosody: XMPP XEP-0065 File Transfer Proxy"
        tcp dport {${lib.concatMapStringsSep "," toString prosody.httpsPorts}} counter accept comment "prosody: HTTPS"
      }
      chain output-net {
        skuid ${prosody.user} counter accept comment "prosody"
      }
    }
  '';
  /*
    services.upnpc.redirections =
    [
    { description = "XMPP";
      externalPort = 5222; protocol = "TCP";
      duration = 30 * 60;
      service.wantedBy = ["prosody.service"];
      service.partOf   = ["prosody.service"];
    }
    { description = "XMPP";
      externalPort = 5269; protocol = "TCP";
      duration = 30 * 60;
      service.wantedBy = ["prosody.service"];
      service.partOf   = ["prosody.service"];
    }
    { description = "XMPP-FTP";
      externalPort = 5000; protocol = "TCP";
      duration = 30 * 60;
      service.wantedBy = ["prosody.service"];
      service.partOf   = ["prosody.service"];
    }
    ] ++ map (externalPort: {
    description = "XMPP-HTTPS";
    inherit externalPort; protocol="TCP";
    duration = 30 * 60;
    service.wantedBy = ["prosody.service"];
    service.partOf   = ["prosody.service"];
    }) prosody.httpsPorts;
  */
  /*
    services.tor.relay.hiddenServices."${domain}/xmpp".map = [ 5222 5269 5000 ] ++ prosody.httpsPorts;
  */
  users.groups.acme.members = [ prosody.user ];
  security.acme.certs."${domain}" = {
    postRun = "systemctl try-restart prosody";
  };
  fileSystems."/var/lib/prosody" = {
    device = "rpool/var/prosody";
    fsType = "zfs";
  };
  services.sanoid.datasets = {
    "rpool/var/prosody" = {
      use_template = [ "snap" ];
      daily = 7;
    };
  };
  systemd.services.prosody = {
    wants = [ "acme-selfsigned-${domain}.service" "acme-${domain}.service" ];
    after = [ "acme-selfsigned-${domain}.service" ];
  };
  # sudo -u prosody prosodyctl check
  services.prosody = {
    enable = true;
    xmppComplianceSuite = true;
    modules = {
      announce = true;
      blocklist = true;
      cloud_notify = false; # not encrypted even with OMEMO
      #cloud_notify_encrypted = true;
      groups = true;
      limits = false;
      motd = true;
      server_contact_info = true;
      watchregistrations = true;
      websocket = false;
      welcome = true;
      proxy65 = false;
    };
    extraModules = [
      "turn_external"
      #"turncredentials"
      #"net_multiplex"
      #"extdisco"
    ];
    extraConfig = ''
      log = {
        -- debug = "*syslog";
        info = "*syslog";
        warn  = "*syslog";
        error = "*syslog";
      }
      -- Listen only in IPv4 until hosting provider's IPv6 works well.
      interfaces = { "0.0.0.0" }
      c2s_interfaces = { "0.0.0.0" }
      contact_info = {
        --abuse = { "mailto:abuse@${domain}", "xmpp:abuse@${domain}" };
        --admin = { "mailto:admin@${domain}", "xmpp:admin@${domain}" };
        --feedback = { "http://${domain}/feedback.php", "mailto:feedback@${domain}", "xmpp:feedback@${domain}" };
        --sales = { "xmpp:bard@${domain}" };
        --security = { "xmpp:security@${domain}" };
        --support = { "http://${domain}/support.php", "xmpp:support@${domain}" };
      }
      legacy_ssl_ports = { 5222 }

      -- turncredentials_host = "turn.${domain}"
      -- turncredentials_port = 3478
      -- turncredentials_secret = "${coturn.static-auth-secret}";

      turn_external_secret = "${coturn.static-auth-secret}"
      turn_external_host = "turn.${domain}"
      turn_external_port = 3478
      turn_external_ttl = 86400

      smacks_enabled_s2s = true;
      smacks_s2s_resend = true;

      --http_files_dir = "/var/lib/prosody/files"
      --http_external_url = "https://tmp.${domain}:5281"
      --https_certificate = "/var/lib/acme/${domain}/fullchain.pem"
      --https_key = "/var/lib/acme/${domain}/key.pem"
      --certificates = "/var/lib/acme"

      proxy65_ports = 5000
      Component "proxy65.${domain}" "proxy65"
        proxy65_address = "proxy65.${domain}"
        proxy65_acl = { "${domain}" }

      Component "biboumi.${domain}"
        component_secret = "useless-secret-on-loopback"
    '';
    httpFileShare = {
      domain = "tmp.${domain}";
      size_limit = 100 * 1024 * 1024; # 100 MiB
      daily_quota = 200 * 1024 * 1024; # 200 MiB per day per user
      global_quota = 1 * 1024 * 1024 * 1024; # 1 GiB total
      expires_after = 7 * 24 * 60 * 60; # 7 days
    };
    #ports = {80};
    #ssl_ports = {443};
    c2sRequireEncryption = true;
    s2sRequireEncryption = true;
    s2sSecureAuth = true;
    muc = [
      {
        domain = "salons.${domain}";
        extraConfig = ''
          restrict_room_creation = "local"
          max_history_messages = 42
          muc_room_locking = true
          muc_room_lock_timeout = 600
          muc_tombstones = true
          muc_tombstone_expiry = 31 * 24 * 60 * 60
          muc_room_default_public = true
          muc_room_default_members_only = false
          muc_room_default_moderated = true
          muc_room_default_public_jids = false
          muc_room_default_change_subject = true
          muc_room_default_history_length = 42
          muc_room_default_language = "fr"
        '';
      }
    ];
    ssl.key = "/var/lib/acme/${domain}/key.pem";
    ssl.cert = "/var/lib/acme/${domain}/fullchain.pem";
    admins = [
      "julm@${domain}"
    ];
    virtualHosts."${domain}" = {
      enabled = true;
      domain = "${domain}";
      ssl.key = "/var/lib/acme/${domain}/key.pem";
      ssl.cert = "/var/lib/acme/${domain}/fullchain.pem";
    };
    allowRegistration = false;
    authentication = "internal_hashed";
    httpPorts = [ ];
    httpsPorts = [ 5281 ];
    disco_items = [
      {
        url = "biboumi.${domain}";
        description = "Passerelle vers des serveurs IRC (Internet Relay Chat)";
      }
    ];
    package = pkgs.prosody.override {
      withCommunityModules = [
        "turncredentials"
        #"extdisco"
      ];
    };
  };
}