{ config, lib, ... }:

let
  cfg = config.local.wireguard;

  serverData = import ../hosts/tatos/data.secret.nix;

  serverAddr = serverData.addr;
  serverPort = serverData.wireguard.port;
in
{
  options.local.wireguard = with lib; {
    enable = mkEnableOption "Enable wireguard vpn";
    ip = mkOption {
      type = types.str;
      description = "10.100.0.<num>/24";
      example = "10.100.0.1/24";
    };
    privateKeyFile = mkOption {
      type = types.str;
    };
  };

  config = lib.mkIf cfg.enable {
    networking.firewall = {
      allowedUDPPorts = [ serverPort ]; # Clients and peers can use the same port, see listenport
    };
    # Enable WireGuard
    networking.wg-quick.interfaces = {
      # "wg0" is the network interface name. You can name the interface arbitrarily.
      wg0 = {
        # Determines the IP address and subnet of the client's end of the tunnel interface.
        address = [ cfg.ip ];
        dns = [ "10.20.30.1" ];

        listenPort = serverPort; # to match firewall allowedUDPPorts (without this wg uses random port numbers)

        # Path to the private key file.
        privateKeyFile = cfg.privateKeyFile;

        peers = [
          # For a client configuration, one peer entry for the server will suffice.

          {
            # Public key of the server (not a file path).
            publicKey = serverData.wireguard.publicKey;

            # Forward all the traffic via VPN.
            allowedIPs = [ "0.0.0.0/0" ];
            # Or forward only particular subnets
            # allowedIPs = [ "192.168.0.0/24" ];

            # Set this to the server IP and port.
            endpoint = "${serverAddr}:${toString serverPort}";

            # Send keepalives every 25 seconds. Important to keep NAT tables alive.
            persistentKeepalive = 15;
          }
        ];
      };
    };
  };
}
