{ pkgs, lib, config, inputs, hosts, ipv4, ... }:
let
  inherit (config.services) prosody;
  inherit (hosts.mermet.config.services) coturn;
  domain = config.networking.domain;
in
{
imports = [
  prosody/biboumi.nix
];
networking.nftables.ruleset = ''
  add rule inet filter net2fw tcp dport {5222,5269} counter accept comment "XMPP"
  add rule inet filter net2fw tcp dport 5000 counter accept comment "XMPP XEP-0065 File Transfer Proxy"
  add rule inet filter net2fw tcp dport {${lib.concatMapStringsSep "," toString prosody.httpsPorts}} counter accept comment "XMPP HTTPS"
  add rule inet filter fw2net meta 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 reload 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 = true;
    groups = true;
    limits = false;
    motd = true;
    server_contact_info = true;
    watchregistrations = true;
    websocket = false;
    welcome = true;
    proxy65 = false;
  };
  extraModules = [
    "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 = "${lib.removeSuffix "\n" (builtins.readFile (inputs.secrets + "/coturn/static-auth-secret"))}";
    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"
  '';
  #ports = {80};
  #ssl_ports = {443};
  c2sRequireEncryption = true;
  s2sRequireEncryption = true;
  s2sSecureAuth = true;
  uploadHttp = {
    domain = "tmp.${domain}";
    # Prosody's HTTP parser limit on body size
    uploadFileSizeLimit = "10485760";
    userQuota = 100 * 1024 * 1024;
    uploadExpireAfter = "60 * 60 * 24 * 7";
    httpUploadPath = "/var/lib/prosody/upload";
  };
  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"
    ];
  };
};
}