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

with lib;
let
  hostname = "clunk";

  primary-ip = "10.0.0.1";

  dns-proxy-port = 5335;

  host-packages = with pkgs; [ nixops ];

  site-name = config.fudo.hosts.${config.instance.hostname}.site;
  site = config.fudo.site.${site-name};

in {
  environment.systemPackages = host-packages;

  networking = {
    interfaces = {
      enp1s0.useDHCP = true;

      enp2s0.useDHCP = false;
      enp3s0.useDHCP = false;
      enp4s0.useDHCP = false;

      intif0 = {
        useDHCP = false;
        ipv4.addresses = [{
          address = primary-ip;
          prefixLength = 16;
        }];
      };
    };

    nat = {
      enable = true;
      externalInterface = "enp1s0";
      internalInterfaces = [ "intif0" ];
      forwardPorts = [{
        destination = "127.0.0.1:53";
        sourcePort = 53;
        proto = "udp";
      }];
    };
  };

  fudo = {

    secrets.host-secrets.${hostname} = let
      files = config.fudo.secrets.files;
    in {
      heimdal-master-key = {
        source-file = files.realm-master-keys."RUS.SELBY.CA";
        target-file = "/run/heimdal/master-key";
        user = config.fudo.auth.kdc.user;
      };
    };

    local-network = let
      host-config = config.fudo.hosts.${config.instance.hostname};
      site-name = host-config.site;
      site = config.fudo.sites.${site-name};
      domain-name = host-config.domain;
      domain = config.fudo.domains.${domain-name};

    in {
      enable = true;
      # NOTE: requests go:
      #  - local bind instance
      #  - pi-hole
      #  - DoH resolver
      domain = domain-name;
      dns-servers = [ primary-ip ];
      gateway = primary-ip;
      dhcp-interfaces = [ "intif0" ];
      dns-listen-ips = [ primary-ip "127.0.0.1" "127.0.1.1" "::1" ];
      recursive-resolver = "${primary-ip} port 5353";
      network = site.network;
      dhcp-dynamic-network = site.dynamic-network;
      search-domains = [ "selby.ca" ];
      enable-reverse-mappings = true;
      zone-definition = config.fudo.zones."rus.selby.ca";
    };

    hosts.clunk.external-interfaces = [ "enp1s0" ];

    garbage-collector = {
      enable = true;
      timing = "weekly";
    };

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

    secure-dns-proxy = {
      enable = true;
      listen-port = dns-proxy-port;
      upstream-dns =
        [ "https://1.1.1.1/dns-query" "https://1.0.0.1/dns-query" ];
      bootstrap-dns = "1.1.1.1";
      allowed-networks =
        [ "1.1.1.1/32" "1.0.0.1/32" "10.0.0.0/16" "localhost" "link-local" ];
      listen-ips = [ primary-ip ];
    };
  };

  virtualisation = {
    docker = {
      enable = true;
      autoPrune.enable = true;
      enableOnBoot = true;
    };

    oci-containers = {
      backend = "docker";
      containers = {
        pihole = {
          image = "pihole/pihole:v5.7";
          autoStart = true;
          ports = [ "5353:53/tcp" "5353:53/udp" "3080:80/tcp" ];
          environment = {
            # ServerIP = primary-ip;
            VIRTUAL_HOST = "dns-hole.rus.selby.ca";
            DNS1 = "${primary-ip}#${toString dns-proxy-port}";
          };
          volumes = [
            "/srv/pihole/etc-pihole/:/etc/pihole/"
            "/srv/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/"
          ];
        };
      };
    };
  };

  services.nginx = {
    enable = true;

    recommendedOptimisation = true;
    recommendedGzipSettings = true;
    recommendedProxySettings = true;

    virtualHosts = {
      "dns-hole.rus.selby.ca" = {
        serverAliases = [
          "pihole.rus.selby.ca"
          "hole.rus.selby.ca"
          "pihole"
          "dns-hole"
          "hole"
        ];

        locations."/" = { proxyPass = "http://127.0.0.1:3080"; };
      };
    };
  };
}