{ config, pkgs, ... }:

{
  c3d2 = {
    hq.statistics.enable = true;
    deployment.server = "server10";
  };

  environment = {
    etc.gitconfig.text = /* gitconfig */ ''
      [url "gitea@gitea.c3d2.de:"]
      insteadOf = https://gitea.c3d2.de/
    '';
    systemPackages = with pkgs; [
      rsync # used in drone CI
    ];
  };

  # changes in knot config cause a rebuild because tools like keymgr are wrapped with the config file *and* contain the man pages
  documentation.man.generateCaches = false;

  networking = {
    hostName = "knot";
    firewall = {
      allowedTCPPorts = [
        # DNS
        53
      ];
      allowedUDPPorts = [
        # DNS
        53
      ];
    };
  };

  services.knot = {
    enable = true;
    keyFiles = [ config.sops.secrets."knot/keyFile".path ];
    settings = {
      acl = [
        {
          id = "jabber";
          key = "jabber";
          action = "update";
          update-owner = "name";
          update-owner-match = "sub-or-equal";
          update-owner-name = [ "jabber.c3d2.de." ];
        }
      ];

      log = [ {
        target = "syslog";
        any = "info";
      } ];

      mod-stats = [ {
        id = "default";
        query-type = "on";
      } ];

      remote = [
        {
          id = "ns.spaceboyz.net";
          address = [ "95.217.229.209" "2a01:4f9:4b:39ec::4" ];
        } {
          # TODO: drop
          id = "ns0.q-ix.net";
          address = [ "217.115.12.65" "2a00:1328:e101:b01::1" ];
        }
        # {
          # TODO
          # id = "ns1.supersandro.de";
          # address = [ "188.34.196.104" "2a01:4f8:1c1c:1d38::1" ];
        # }
      ];

      remotes = [ {
        id = "all";
        remote = [ "ns.spaceboyz.net" "ns0.q-ix.net" /*"ns1.supersandro.de"*/ ];
      } ];

      server = {
        answer-rotation = true;
        automatic-acl = true;
        identity = "ns1.supersandro.de";
        listen = [
          "172.20.73.61"
          "2a00:8180:2c00:282:2041:cbff:fe0c:8516"
          "2a00:8180:2c00:282:cd7:56ff:fe69:6366"
          "fd23:42:c3d2:582:2041:cbff:fe0c:8516"
          "fd23:42:c3d2:582:cd7:56ff:fe69:6366"
        ];
        tcp-fastopen = true;
        version = null;
      };

      template = [ {
        id = "default";
        # dnssec-signing = true; ???
        file = "%s.zone";
        global-module = [ "mod-stats" ];
        journal-content = "all"; # required for zonefile-load=difference-no-serial and makes cold starts like zone reloads
        module = "mod-stats/default";
        semantic-checks = true;
        serial-policy = "dateserial";
        storage = "/var/lib/knot/zones";
        zonefile-load = "difference-no-serial";
      } ];

      zone = map (zone: {
        inherit (zone) domain;
        template = "default";
        notify = [ "all" ];
      }) [
        { domain = "c3dd.de"; }
        { domain = "c3d2.de"; }
        { domain = "hq.c3d2.de"; }
        { domain = "dyn.hq.c3d2.de"; }
        # TODO: consolidate
        { domain = "inbert.c3d2.de"; }
        { domain = "c3d2.ffdd"; }
        { domain = "c3d2.space"; }
        { domain = "c3d2.social"; }
        { domain = "cccdd.de"; }
        { domain = "dresden.ccc.de"; }
        { domain = "datenspuren.de"; }
        { domain = "netzbiotop.org"; }
        { domain = "pentamedia.org"; }
        { domain = "zentralwerk.ffdd"; }

        { domain = "2001-67c-1400-2240.ip6.arpa"; }
        { domain = "99.22.172.in-addr.arpa"; }
      ];
    };
  };

  security.sudo.extraRules = [ {
    users = [ "knot" ];
    commands = [ {
      command = "/etc/profiles/per-user/knot/bin/reload-knot";
      options = [ "NOPASSWD" ];
    } ];
  } ];

  sops = {
    defaultSopsFile = ./secrets.yaml;
    secrets = {
     "knot/keyFile".owner = "knot";
     "ssh-keys/knot/private" = {
        owner = "knot";
        path = "${config.users.users.knot.home}/.ssh/id_ed25519";
      };
      "ssh-keys/knot/public" = {
        owner = "knot";
        path = "${config.users.users.knot.home}/.ssh/id_ed25519.pub";
      };
    };
  };

  system.stateVersion = "23.11";

  users.users.knot = {
    home = "/var/lib/knot/zones/";
    openssh.authorizedKeys.keys = [
      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHIkIN1gi5cX2wV2WuNph/QzVK7vvYkvqnR/P69s36mZ drone@c3d2"
    ];
    packages = [
      (pkgs.writeScriptBin "reload-knot" ''
        knotc reload
      '')
    ];
    useDefaultShell = true;
  };
}
