{ pkgs, ... }:
# let
#   heimdall_hosts = lib.attrsets.filterAttrs (k: v: builtins.elem "heimdall.zto" v) config.networking.hosts;
#   heimdall_ipv4 = builtins.elemAt 0 (builtins.attrNames heimdall_hosts);
# in
{

  boot = {
    growPartition = true;
    kernelParams = [
      "console=ttyS0"
      "panic=1"
      "boot.panic_on_fail"
    ];
    initrd.kernelModules = [ "virtio_scsi" ];
    kernelModules = [
      "virtio_pci"
      "virtio_net"
    ];
    loader = {
      grub.device = "/dev/sda";
      timeout = 0;
      grub.configurationLimit = 0;
    };
  };

  console = {
    font = "Lat2-Terminus16";
    keyMap = "it";
  };

  environment = {
    pathsToLink = [ "/share/zsh" ];
    systemPackages = [
      pkgs.helix
      pkgs.zellij
      pkgs.kitty.terminfo
    ];
  };

  i18n.defaultLocale = "it_IT.UTF-8";

  programs = {
    gnupg.agent = {
      enable = true;
      enableSSHSupport = true;
    };
    zsh.enable = true;
  };

  networking.hostName = "baldur";

  time.timeZone = "Europe/Rome";

  services = {
    fail2ban = {
      enable = true;
      bantime-increment.enable = true;
      jails = {
        "nginx-botsearch" = ''
          filter = nginx-botsearch
          action =  nftables-multiport[name=HTTP, port="http,https"]
          logpath = /var/log/nginx/error.log*
          backend = auto
        '';
        "nginx-http-auth" = ''
          filter = nginx-http-auth
          action =  nftables-multiport[name=HTTP, port="http,https"]
          logpath = /var/log/nginx/error.log*
          backend = auto
        '';
      };
    };
    nginx = {
      enable = true;
      recommendedProxySettings = true;
      recommendedOptimisation = true;
      recommendedGzipSettings = true;
      recommendedTlsSettings = true;
      virtualHosts =
        let
          ssl = {
            enableACME = true;
            forceSSL = true;
          };
        in
        {
          "me.bertof.net" = ssl // {
            locations."/".extraConfig = "rewrite ^/(.*)$ https://homes.di.unimi.it/berto/$1 redirect ;";
          };
          "home-assistant.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://loki.tsn:8123/";
              proxyWebsockets = true;
            };
            extraConfig = ''
              proxy_pass_header Authorization;
              proxy_buffering off;
            '';
          };
          "s3.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:9000/";
              proxyWebsockets = true;
            };
            extraConfig = ''
              client_max_body_size 6g;
              proxy_pass_header Authorization;
              proxy_buffering off;
            '';
          };
          "hass.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:8123/";
              proxyWebsockets = true;
            };
            extraConfig = ''
              proxy_pass_header Authorization;
              proxy_buffering off;
            '';
          };
          "ntfy.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:7080/";
              proxyWebsockets = true;
              extraConfig = ''
                client_max_body_size 5g;
              '';
            };
          };
          "my-nextcloud.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:80/";
              proxyWebsockets = true;
              extraConfig = ''
                client_max_body_size 5g;
              '';
            };
          };
          "grafana.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:3000/";
              proxyWebsockets = true;
              extraConfig = ''
                client_max_body_size 5g;
              '';
            };
          };
          "radarr.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:7878/";
              proxyWebsockets = true;
            };
          };
          "sonarr.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:8989/";
              proxyWebsockets = true;
            };
          };
          "lidarr.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:8686/";
              proxyWebsockets = true;
            };
          };
          # "ombi.bertof.net" = ssl // { locations."/" = { proxyPass = "http://heimdall.tsn:5000/"; proxyWebsockets = true; }; };
          "jellyfin.bertof.net" = ssl // {
            locations."/" = {
              proxyPass = "http://heimdall.tsn:8096/";
              proxyWebsockets = true;
            };
          };
        };
    };
    openssh = {
      enable = true;
      openFirewall = true;
    };
    # wgautomesh = {
    #   enable = true;
    #   settings = {
    #     interface = "wg0";
    #   };
    # };
  };

  security.acme = {
    acceptTerms = true;
    defaults.email = "filippo.berto95@gmail.com";
  };

  users.users.bertof = {
    isNormalUser = true;
    extraGroups = [
      "audio"
      "input"
      "docker"
      "libvirtd"
      "network"
      "networkmanager"
      "usb"
      "video"
      "wheel"
    ];
    shell = pkgs.zsh;
  };

  boot.kernel.sysctl = {
    "net.ipv4.conf.all.forwarding" = true;
    "net.ipv4.conf.default.forwarding" = true;
  };

  # services.dnsmasq = {
  #   enable = true;
  #   settings = {
  #     server = [ "1.1.1.1" "8.8.8.8" ];
  #     interface = "wg0";
  #   };
  #   # extraConfig = ''
  #   #   interface=wg0
  #   # '';
  # };

  networking = {
    firewall = {
      enable = true;
      allowPing = true;
      allowedTCPPorts = [
        80
        443
        53
      ];
      allowedUDPPorts = [
        53
        51820
      ];
      # interfaces.ens3.allowedTCPPorts = [ 52123 53 ];
      # interfaces.ens3.allowedUDPPorts = [ 53 ];
      # extraCommands = ''iptables -t raw -A OUTPUT -p udp -m udp --dport 137 -j CT --helper netbios-ns'';
    };

    nat = {
      enable = true;
      enableIPv6 = true;
      externalInterface = "ens3";
      internalInterfaces = [ "wg0" ];
    };

    # wireguard = {
    #   enable = true;
    #   interfaces.wg0 = {
    #     privateKeyFile = config.age.secrets.baldur_wg_priv.path;
    #     ips = [ "10.10.10.1/24" "fc10:10:10::1/64" ];
    #     listenPort = 52123;

    #     # # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
    #     # postSetup = ''
    #     #   ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT
    #     #   ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.10.10.1/24 -o ens3 -j MASQUERADE
    #     #   ${pkgs.iptables}/bin/ip6tables -A FORWARD -i wg0 -j ACCEPT
    #     #   ${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s fc10:10:10::1/64 -o ens3 -j MASQUERADE
    #     # '';

    #     # # Undo the above
    #     # postShutdown = ''
    #     #   ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT
    #     #   ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.10.10.1/24 -o ens3 -j MASQUERADE
    #     #   ${pkgs.iptables}/bin/ip6tables -D FORWARD -i wg0 -j ACCEPT
    #     #   ${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s fc10:10:10::1/64 -o ens3 -j MASQUERADE
    #     # '';

    #     peers = [
    #       # {
    #       #   # baldur
    #       #   allowedIPs = [ "10.10.10.2/32" "fc10:10:10::2/128" ];
    #       #   publicKey = "K57ikgFSR1O0CXWBxfQEu7uxSOsp3ePj/NMRets5pVc=";
    #       #   presharedKeyFile = config.age.secrets.baldur_wg_psk.path;
    #       # }
    #       {
    #         # odin
    #         allowedIPs = [ "10.10.10.2/32" "fc10:10:10::2/128" ];
    #         publicKey = "LDBhvzeYmHJ0z5ch+N559GWjT3It1gZvGR/9WtCfURw=";
    #         # presharedKeyFile = config.age.secrets.odin_wg_psk.path;
    #       }
    #     ];
    #   };
    # };
    # wg-quick.interfaces.wg0 = {
    #   address = [ "10.0.0.1/24" "fdc9:281f:04d7:9ee9::1/64" ];
    #   listenPort = 51820;
    #   privateKeyFile = config.age.secrets.baldur_wg_priv.path;

    #   # This allows the wireguard server to route your traffic to the internet and hence be like a VPN
    #   postUp = ''
    #     ${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -j ACCEPT
    #     ${pkgs.iptables}/bin/iptables -t nat -A POSTROUTING -s 10.0.0.1/24 -o ens3 -j MASQUERADE
    #     ${pkgs.iptables}/bin/ip6tables -A FORWARD -i wg0 -j ACCEPT
    #     ${pkgs.iptables}/bin/ip6tables -t nat -A POSTROUTING -s fdc9:281f:04d7:9ee9::1/64 -o ens3 -j MASQUERADE
    #   '';

    #   # Undo the above
    #   preDown = ''
    #     ${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -j ACCEPT
    #     ${pkgs.iptables}/bin/iptables -t nat -D POSTROUTING -s 10.0.0.1/24 -o ens3 -j MASQUERADE
    #     ${pkgs.iptables}/bin/ip6tables -D FORWARD -i wg0 -j ACCEPT
    #     ${pkgs.iptables}/bin/ip6tables -t nat -D POSTROUTING -s fdc9:281f:04d7:9ee9::1/64 -o ens3 -j MASQUERADE
    #   '';

    #   peers = [
    #     {
    #       # odin
    #       publicKey = "LDBhvzeYmHJ0z5ch+N559GWjT3It1gZvGR/9WtCfURw=";
    #       presharedKeyFile = config.age.secrets.wg_psk.path;
    #       allowedIPs = [ "10.0.0.2/32" "fdc9:281f:04d7:9ee9::2/128" ];
    #     }
    #     {
    #       # oppo
    #       publicKey = "OBk6bHKuIYLwD7cwjmAuMn57jXqbDwCL52jhQxiHnnA=";
    #       presharedKeyFile = config.age.secrets.wg_psk.path;
    #       allowedIPs = [ "10.0.0.3/32" "fdc9:281f:04d7:9ee9::3/128" ];
    #     }
    #     {
    #       # thor
    #       publicKey = "rpwR6n4IE96VZAmQDBufsWE/a9G7d8fpkvY1OwsbOhk=";
    #       presharedKeyFile = config.age.secrets.wg_psk.path;
    #       allowedIPs = [ "10.0.0.4/32" "fdc9:281f:04d7:9ee9::4/128" ];
    #     }
    #   ];
    # };
  };

  system = {
    stateVersion = "23.05";
    autoUpgrade.allowReboot = true;
  };
}
