{ config, lib, ... }:

let
  inherit (lib) mkOption;

in
{
  options = {
    procolix.vm = {
      name = mkOption { };
      ip4 = mkOption { };
      ip6 = mkOption { };
    };
  };

  config = {
    services.openssh.enable = true;

    networking = {
      hostName = config.procolix.vm.name;
      domain = "procolix.com";
      interfaces = {
        eth0 = {
          ipv4 = {
            addresses = [
              {
                address = config.procolix.vm.ip4;
                prefixLength = 24;
              }
            ];
          };
          ipv6 = {
            addresses = [
              {
                address = config.procolix.vm.ip6;
                prefixLength = 64;
              }
            ];
          };
        };
      };
      defaultGateway = {
        address = "185.206.232.1";
        interface = "eth0";
      };
      defaultGateway6 = {
        address = "2a00:51c0:12:1201::1";
        interface = "eth0";
      };
      nameservers = [
        "95.215.185.6"
        "95.215.185.7"
        "2a00:51c0::5fd7:b906"
      ];
      firewall.enable = false;
      nftables = {
        enable = true;
        ruleset = ''
          #!/usr/sbin/nft -f

          flush ruleset

          ########### define usefull variables here #####################
          define wan        = eth0
          define ssh_allow  = {
                      83.161.147.127/32, # host801 ipv4
                      95.215.185.92/32,  # host088 ipv4
                      95.215.185.211/32, # host089 ipv4
                      95.215.185.34/32,  # nagios2 ipv4
                      95.215.185.181/32, # ansible.procolix.com
                      95.215.185.235,        # ansible-hq
                  }
          define snmp_allow = {
                      95.215.185.31/32,   # cacti ipv4
                  }
          define nrpe_allow = {
                      95.215.185.34/32,   # nagios2 ipv4
                  }

          ########### here starts the automated bit #####################
          table inet filter {
              chain input {
                  type filter hook input priority 0;
                  policy drop;

                  # established/related connections
                  ct state established,related accept
                  ct state invalid drop

                  # Limit ping requests.
                  ip protocol icmp icmp type echo-request limit rate over 10/second burst 50 packets drop
                  ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 50 packets drop

                  # loopback interface
                  iifname lo accept

                  # icmp
                  ip protocol icmp icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } accept
                  # Without the nd-* ones ipv6 will not work.
                  ip6 nexthdr icmpv6 icmpv6 type { destination-unreachable, echo-reply, echo-request, nd-neighbor-solicit,  nd-router-advert, nd-neighbor-advert, packet-too-big, parameter-problem, time-exceeded } accept

                  # open tcp ports: sshd (22)
                  tcp dport {ssh} accept

                  # open tcp ports: snmp (161)
                  ip saddr $snmp_allow udp dport {snmp} accept

                  # open tcp ports: nrpe (5666)
                  ip saddr $nrpe_allow tcp dport {nrpe} accept

                  # open tcp ports: http (80,443)
                  tcp dport {http,https} accept
              }
              chain forward {
                  type filter hook forward priority 0;
              }
              chain output {
                  type filter hook output priority 0;
              }
          }

          table ip nat {
              chain postrouting {
              }
              chain prerouting {
              }
          }
        '';
      };
    };
  };
}