{config, pkgs, lib, ...}: with lib; let

  cfg = config.services.headscale;

  authServer = cfg.settings.server_url;
  
  connectContainer = name: options: {
    enableTun = true;
    bindMounts = {
      "/var/tailauth" = {
        hostPath = cfg.ensureUsers."${name}".path;
      };
    };
    config = {config, pkgs, ...}: {
      networking.nameservers = [ "1.1.1.1" ];
      networking.useHostResolvConf = false;

      networking.firewall = {
        enable = false;
      };
      
      services.tailscale = {
        enable = true;
        useRoutingFeatures = "client";
        authKeyFile = "/var/tailauth";
        extraUpFlags = ["--login-server" "${authServer}"];
      };
    };
  };

  mkContainerAfterToken = name: options: {
    requires = ["headscale-preauth-regen-${name}.service"];
    after = ["headscale-preauth-regen-${name}.service"];
  };

  ensureContainerUser = name: options: {
    
  };
  
in {
  # Extend NixOS containers to automatically
  # create a headscale user with the container
  # name, generate its auth, and binds it to
  # the container
  imports = [
    ./headscale.nix
  ];

  options = {
    services.headscale.containers = mkOption {
      type = types.attrsOf (types.submodule (
        {config, options, name, ...}:
        {
          
        }
      ));
      default = {};
    };
  };

  config = {
    networking.bridges = {
      "br0" = {
        interfaces = [];
      };
    };
    networking.interfaces.br0.ipv4.addresses = [{
      address = "10.0.0.1";
      prefixLength = 24;
    }];
    networking.nat = {
      enable = true;
      # Check for hostBridge use vb instead of ve
      internalInterfaces = (map (n: "vb-${n}") (attrNames cfg.containers)) ++ ["br0"];
      externalInterface = "enp0s25";
      enableIPv6 = true;
    };
    containers = mapAttrs connectContainer cfg.containers;
    systemd.services = mapAttrs' (n: v: nameValuePair "container@${n}" (mkContainerAfterToken n v)) cfg.containers;
    services.headscale.ensureUsers = mapAttrs ensureContainerUser cfg.containers;
  };
}
