{ config, lib, pkgs, ... }:

with lib;
let
  hostname = "nutboy3";
  host-fqdn = config.instance.host-fqdn;
  host-ipv4 = "199.87.154.175";
  domain-name = config.fudo.hosts.${hostname}.domain;
  domain = config.fudo.domains.${domain-name};
  site-name = config.fudo.hosts.${hostname}.site;
  site = config.fudo.sites.${site-name};

  local-packages = with pkgs; [ ldns.examples ];

  secrets = config.fudo.secrets.host-secrets.${hostname};

  postgresql-user =
    config.systemd.services.postgresql.serviceConfig.User;

  files = config.fudo.secrets.files;

  acme-copies = config.fudo.acme.host-domains.${hostname};

in {

  config = {
    networking = {
      nameservers = [ "1.1.1.1" ];
      defaultGateway = {
        address = site.gateway-v4;
        interface = "extif0";
      };

      interfaces.extif0.ipv4.addresses = [{
        address = host-ipv4;
        prefixLength = 31;
      }];
    };

    systemd.tmpfiles.rules = [
      "L /etc/adjtime - - - - /state/etc/adjtime"
    ];

    environment.systemPackages = local-packages;

    fudo = {
      hosts.${hostname}.external-interfaces = [ "extif0" ];

      secrets.host-secrets.nutboy3 = let
        files = config.fudo.secrets.files;
      in {
        heimdal-master-key = {
          source-file = files.realm-master-keys."FUDO.ORG";
          target-file = "/run/heimdal/master-key";
          user = config.fudo.auth.kdc.user;
        };

        ldap-keytab = {
          source-file = files.service-keytabs.${hostname}.openldap;
          target-file = "/run/openldap/ldap.keytab";
          user = config.services.openldap.user;
        };

        postgresql-keytab = {
          source-file = files.service-keytabs.nutboy3.postgres;
          target-file = "/run/postgresql/postgres.keytab";
          user = postgresql-user;
        };
      };

      acme.host-domains.${hostname}.${host-fqdn}.local-copies = {
        openldap = {
          user = config.services.openldap.user;
          dependent-services = [ "openldap.service" ];
          part-of = [ config.fudo.auth.ldap-server.systemd-target ];
        };

        postgresql = {
          user = postgresql-user;
          dependent-services = [ "postgresql.service" ];
          part-of = [ config.fudo.postgresql.systemd-target ];
        };
      };

      client.dns = {
        ipv4 = true;
        ipv6 = true;
        user = "fudo-client";
        external-interface = "extif0";
      };

      auth = {
        ldap-server = let
          ldap-copy = acme-copies.${host-fqdn}.local-copies.openldap;
        in {
          enable = true;
          base = "dc=fudo,dc=org";
          organization = "Fudo";
          kerberos-host = host-fqdn;
          kerberos-keytab = secrets.ldap-keytab.target-file;
          listen-uris = [ "ldap:///" "ldaps:///" "ldapi:///"];
          required-services = [ ldap-copy.service ];

          users = config.fudo.users;
          groups = config.fudo.groups;
          system-users = config.fudo.system-users;

          state-directory = "/state/openldap";

          ssl-chain = ldap-copy.chain;
          ssl-certificate = ldap-copy.certificate;
          ssl-private-key = ldap-copy.private-key;
          ssl-ca-certificate = "${pkgs.letsencrypt-ca}";
        };

        kdc = {
          master-key-file =
            secrets.heimdal-master-key.target-file;
          state-directory = "/state/kerberos";
        };
      };

      # dns.state-directory = "/state/nsd";

      # mail-server = {
      #   enableContainer = true;
      #   debug = true;

      #   domain = domain-name;
      #   mail-hostname = "${host-fqdn}";
      #   monitoring = false;
      #   mail-user = "mailuser";
      #   mail-user-id = 525;
      #   mail-group = "mailgroup";
      #   clamav.enable = true;
      #   dkim.signing = true;

      #   dovecot = {
      #     ssl-certificate = acme-certificate "imap.${domain-name}";
      #     ssl-private-key = acme-private-key "imap.${domain-name}";
      #   };

      #   postfix = {
      #     ssl-certificate = acme-certificate "smtp.${domain-name}";
      #     ssl-private-key = acme-private-key "smtp.${domain-name}";
      #   };

      #   # This should NOT include the primary domain
      #   local-domains = [ host-fqdn "smtp.${domain-name}" ];

      #   mail-directory = "/srv/mailserver/mail";
      #   state-directory = "/srv/mailserver/state";

      #   trusted-networks = [ "172.86.179.16/29" "127.0.0.0/16" ];

      #   alias-users = {
      #     root = [ "niten" ];
      #     postmaster = [ "niten" ];
      #     hostmaster = [ "niten" ];
      #     webmaster = [ "niten" ];
      #     system = [ "niten" ];
      #     admin = [ "niten" ];
      #     dmarc-report = [ "niten" ];
      #   };
      # };

      postgresql = let
        cert-copy =
          config.fudo.acme.host-domains.${hostname}.${host-fqdn}.local-copies.postgresql;
      in {
        enable = true;
        ssl-certificate = cert-copy.full-certificate;
        ssl-private-key = cert-copy.private-key;
        keytab = secrets.postgresql-keytab.target-file;
        local-networks = config.instance.local-networks;
        state-directory = "/state/postgresql";
        required-services = [ cert-copy.service ];
      };

      # git = {
      #   enable = true;
      #   hostname = "git.informis.land";
      #   site-name = "informis git";
      #   user = "gituser";
      #   repository-dir = /srv/git/repo;
      #   state-dir = /srv/git/state;
      #   database = {
      #     user = "gituser";
      #     password-file =
      #       secrets.gitea-database-password.target-file;
      #     hostname = "127.0.0.1";
      #     name = "git";
      #   };
      #   ssh = {
      #     listen-ip = host-ipv4;
      #     listen-port = 2222;
      #   };
      # };
    };

    containers.cashew = let
      local-packages = with pkgs; [
        bind
        emacs-nox
        mtr
        vim
      ];
    in {
      autoStart = true;

      bindMounts = {
        "/state" = {
          hostPath = "/state/cashew";
          isReadOnly = false;
        };
        "/etc/bind" = {
          hostPath = "/state/cashew/bind";
          isReadOnly = false;
        };
        "/var/log" = {
          hostPath = "/state/cashew/logs";
          isReadOnly = false;
        };
        "/home" = {
          hostPath = "/state/cashew/home";
          isReadOnly = false;
        };
        "/etc/dns-root-data" = {
          hostPath = "${pkgs.dns-root-data}/";
          isReadOnly = true;
        };
      };

      interfaces = [ "eno2" ];

      config = { ... }: {
        nixpkgs.pkgs = pkgs;

        environment.systemPackages = local-packages;

        users = {
          users = {
            niten = config.users.users.niten;
            reaper = config.users.users.reaper // {
              openssh.authorizedKeys.keys = [
                "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADtR1gMK7JnIOht8yZNPROr+0VHgt5eWrGFPscVPk1crVuEvIv1MF544Qk1IHi+2OA2xUvI1BTgmXp3TLvCjEn4lQF4Uc5hcUGENS6TNMPByHx69rAeXVMtmjW0sL4Tbhqd0iNh85STdtzXNZUY31+A6ugrJSnvnSt5wv9ZpMz0SFIE1Q=="
              ];
            };
            root.openssh.authorizedKeys.keys = [
              "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBADtR1gMK7JnIOht8yZNPROr+0VHgt5eWrGFPscVPk1crVuEvIv1MF544Qk1IHi+2OA2xUvI1BTgmXp3TLvCjEn4lQF4Uc5hcUGENS6TNMPByHx69rAeXVMtmjW0sL4Tbhqd0iNh85STdtzXNZUY31+A6ugrJSnvnSt5wv9ZpMz0SFIE1Q=="
            ];
          };
          groups = {
            wheel.members = [
              "niten"
              "reaper"
            ];
            dns = {
              members = [
                "niten"
                "reaper"
                "named"
              ];
            };
          };
        };

        networking = {
          defaultGateway = {
            address = "208.81.4.81";
            interface = "eno2";
          };

          interfaces.eno2 = {
            ipv4.addresses = [
              {
                address = "208.81.4.82";
                prefixLength = 29;
              }
              {
                address = "208.81.1.141";
                prefixLength = 32;
              }
            ];
          };

          firewall.enable = false;
        };

        services = {
          bind = {
            enable = true;
            configFile = "/etc/bind/named.conf";
          };

          openssh = {
            enable = true;
            startWhenNeeded = true;
            useDns = true;
            permitRootLogin = "prohibit-password";
            hostKeys = [
              {
                path = "/state/ssh/ssh_host_ed25519_key";
                type = "ed25519";
              }
              {
                path = "/state/ssh/ssh_host_rsa_key";
                type = "rsa";
                bits = 4096;
              }
            ];
          };
        };
      };
    };
  };
}