{ pkgs, lib, config, inputs, hosts, info, ... }:
let
  domain = "autogeree.net";
  domainID = lib.replaceStrings [ "." ] [ "_" ] domain;
  inherit (config) networking;
  inherit (config.services) knot;
  inherit (config.users) users groups;
  zoneData =
    # TODO: increase the TTL once things have settled down
    ''
      $ORIGIN ${domain}.
      $TTL 500

      ; SOA (Start Of Authority)
      @ SOA ns root (
        ${toString inputs.self.lastModified} ; Serial number
        24h   ; Refresh
        15m   ; Retry
        1000h ; Expire (1000h)
        1d    ; Negative caching
      )

      ; NS (Name Server)
      @ NS ns
      @ NS ${info.gandi.dns.secondary.ns.name}.
      ;@ NS ns0.muarf.org.

      ; A (DNS -> IPv4)
      @          A ${hosts.mermet._module.args.ipv4}
      mermet     A ${hosts.mermet._module.args.ipv4}
      autoconfig A ${hosts.mermet._module.args.ipv4}
      code       A ${hosts.mermet._module.args.ipv4}
      git        A ${hosts.mermet._module.args.ipv4}
      imap       A ${hosts.mermet._module.args.ipv4}
      mail       A ${hosts.mermet._module.args.ipv4}
      ns         A ${hosts.mermet._module.args.ipv4}
      pleroma    A ${hosts.mermet._module.args.ipv4}
      pop        A ${hosts.mermet._module.args.ipv4}
      smtp       A ${hosts.mermet._module.args.ipv4}
      submission A ${hosts.mermet._module.args.ipv4}
      www        A ${hosts.mermet._module.args.ipv4}
      chomsky    A 91.216.110.36
      alpes      A 195.88.84.51

      ; SPF (Sender Policy Framework)
      @ 3600 IN SPF "v=spf1 mx ip4:${hosts.mermet._module.args.ipv4} -all"
      @ 3600 IN TXT "v=spf1 mx ip4:${hosts.mermet._module.args.ipv4} -all"

      ; MX (Mail eXchange)
      @ 180 MX 5 mail

      ; SRV (SeRVice)
      _git._tcp.git 18000 IN SRV 0 0 9418 git

      ; CAA (Certificate Authority Authorization)
      ; DOC: https://blog.qualys.com/ssllabs/2017/03/13/caa-mandated-by-cabrowser-forum
      @ CAA 128 issue "letsencrypt.org; validationmethods=dns-01"
    '';
  # Incorrect:
  #@ CAA 128 issue "letsencrypt.org; validationmethods=dns-01; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/79737822"
in
{
  services.knot.settingsFreeform = {
    acl."acl_localhost_acme_${domainID}" = {
      address = "127.0.0.1";
      action = "update";
      update-owner = "name";
      update-owner-match = "equal";
      update-owner-name = [ "_acme-challenge" ];
      update-type = [ "TXT" ];
    };
    acl."acl_tsig_acme_${domainID}" = {
      key = "acme_${domainID}";
      action = "update";
      update-owner = "name";
      update-owner-match = "equal";
      update-owner-name = [ "_acme-challenge" ];
      update-type = [ "TXT" ];
    };
    zone."${domain}" = {
      file = "${domain}.zone";
      serial-policy = "increment";
      semantic-checks = true;
      notify = [
        "secondary_gandi"
        #"secondary_muarf"
      ];
      acl = [
        "acl_gandi"
        #"acl_muarf"
        "acl_localhost_acme_${domainID}"
        "acl_tsig_acme_${domainID}"
      ];
      dnssec-signing = true;
      dnssec-policy = "ed25519";
    };
  };
  networking.nftables.ruleset = ''
    table inet filter {
      set output-net-knot-ipv4 { type ipv4_addr; elements = { ${info.gandi.dns.secondary.transfer.ipv4} }; }
      set output-net-knot-ipv6 { type ipv6_addr; elements = { ${info.gandi.dns.secondary.transfer.ipv6} }; }
    }
  '';
  services.knot = {
    keyFiles = [
      "/run/credentials/knot.service/${domain}.acme.conf"
    ];
  };
  systemd.services.knot = {
    serviceConfig = {
      ExecStartPre = [
        ''
          +${pkgs.coreutils}/bin/install -D -o ${users.knot.name} -g ${groups."knot".name} -m 700 \
           ${pkgs.writeText "${domain}.zone" zoneData} \
           /var/lib/knot/zones/${domain}.zone
        ''
      ];
      LoadCredentialEncrypted = [
        "${domain}.acme.conf:${builtins.path { path = ./. + "/${domain}/acme.conf.cred"; }}"
      ];
    };
  };
  /* Useless since the zone is public
    services.unbound.settings = {
    stub-zone = {
    name = domain;
    stub-addr = "127.0.0.1@5353";
    };
    };
    '';
  */
}