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

with lib;
let
  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 {
  system = {
    # # DO force all DNS traffic to use the local server
    # activationScripts.force-local-dns = let
    #   wifi-ip =
    #     config.fudo.networks."rus.selby.ca".hosts.google-wifi.ipv4-address;
    # in ''
    #   ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p udp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
    #   ${pkgs.iptables}/bin/iptables -t nat -A OUTPUT -p tcp -s ${wifi-ip} --dport 53 -j DNAT --to ${primary-ip}:53
    # '';
  };

  environment.systemPackages = host-packages;

  fudo.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;
    network-definition = config.fudo.networks."rus.selby.ca";
  };

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

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

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

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

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

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

    auth.kdc = {
      enable = true;
      realm = "RUS.SELBY.CA";
      bind-addresses = [ "10.0.0.1" "127.0.0.1" "::1" ];
      acl = {
        "niten" = { perms = [ "add" "change-password" "list" ]; };
        "*/root" = { perms = [ "all" ]; };
      };
    };

    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"; };
      };
    };
  };
}