/*

Name:     https://matrix.fandom.com/wiki/Agent_Jones
Type:     Physical
Hardware: PowerEdge r210
From:     2011 (?)
Role:     Firewall
Notes:    Used to have Agent Smith as a partner but it died (Ironically)
*/
{
  pkgs,
  lib,
  nodes,
  ...
}: let
  # name of the server, sets teh hostname and record for it
  name = "agentjones";
  ip_pub = "193.1.99.72";
  hostname = "${name}.skynet.ie";
  host = {
    ip = ip_pub;
    name = name;
    hostname = hostname;
  };
in {
  imports = [
    ./hardware/RM001.nix
  ];

  deployment = {
    targetHost = hostname;
    targetPort = 22;
    targetUser = null;

    # somehow ssh from runner to this fails
    tags = ["active-firewall"];
  };

  services.skynet = {
    host = host;
    backup.enable = true;
  };

  # keep the wired usb connection alive (front panel)
  # networking.interfaces.enp0s29u1u5u2.useDHCP = true;

  networking.hostName = name;
  # this has to be defined for any physical servers
  # vms are defined by teh vm host
  networking = {
    defaultGateway.interface = lib.mkForce "eno1";
    interfaces.eno1.ipv4.addresses = [
      {
        address = ip_pub;
        prefixLength = 26;
      }
    ];
  };

  # this server is teh firewall
  skynet_firewall = {
    # always good to know oneself

    own = {
      ip = ip_pub;

      ports = {
        tcp = [
          # ssh in
          22
        ];
        udp = [];
      };
    };

    enable = false;

    # gonna have to get all the
    forward = builtins.concatLists (
      # using this function "(key: value: value.config.skynet_firewall.forward)" turn the values ointo a list
      lib.attrsets.mapAttrsToList (
        key: value:
        # make sure that anything running this firewall dosent count (recursion otherewise)
        # firewall may want to open ports in itself but can deal with that later
          if builtins.hasAttr "skynet_firewall" value.config
          then
            (
              if value.config.skynet_firewall.enable
              then []
              else value.config.skynet_firewall.forward
            )
          else []
      )
      nodes
    );
  };
}