{ lib, ... }:

let
  certs = import ./common/acme/server/snakeoil-certs.nix;
  domain = certs.domain;
in

{
  name = "wstunnel";

  meta.platforms = lib.platforms.linux;

  nodes = {
    server = {
      virtualisation.vlans = [ 1 ];

      security.pki.certificateFiles = [ certs.ca.cert ];

      networking = {
        useNetworkd = true;
        useDHCP = false;
        firewall.enable = false;
      };

      systemd.network.networks."01-eth1" = {
        name = "eth1";
        networkConfig.Address = "10.0.0.1/24";
      };

      services.wstunnel = {
        enable = true;
        servers.my-server = {
          listen = {
            host = "10.0.0.1";
            port = 443;
          };
          tlsCertificate = certs.${domain}.cert;
          tlsKey = certs.${domain}.key;
        };
      };
    };

    client = {
      virtualisation.vlans = [ 1 ];

      security.pki.certificateFiles = [ certs.ca.cert ];

      networking = {
        useNetworkd = true;
        useDHCP = false;
        firewall.enable = false;
        extraHosts = ''
          10.0.0.1 ${domain}
        '';
      };

      systemd.network.networks."01-eth1" = {
        name = "eth1";
        networkConfig.Address = "10.0.0.2/24";
      };

      services.wstunnel = {
        enable = true;
        clients.my-client = {
          autoStart = false;
          connectTo = "wss://${domain}:443";
          localToRemote = [ "tcp://8080:localhost:2080" ];
          remoteToLocal = [ "tcp://2081:localhost:8081" ];
        };
      };
    };
  };

  testScript = # python
    ''
      start_all()
      server.wait_for_unit("wstunnel-server-my-server.service")
      client.wait_for_open_port(443, "10.0.0.1")

      client.systemctl("start wstunnel-client-my-client.service")
      client.wait_for_unit("wstunnel-client-my-client.service")

      with subtest("connection from client to server"):
        server.succeed("nc -l 2080 >/tmp/msg &")
        client.sleep(1)
        client.succeed('nc -w1 localhost 8080 <<<"Hello from client"')
        server.succeed('grep "Hello from client" /tmp/msg')

      with subtest("connection from server to client"):
        client.succeed("nc -l 8081 >/tmp/msg &")
        server.sleep(1)
        server.succeed('nc -w1 localhost 2081 <<<"Hello from server"')
        client.succeed('grep "Hello from server" /tmp/msg')

      client.systemctl("stop wstunnel-client-my-client.service")
    '';
}