{ lib, pkgs, config, ... }:
let
  cfg = config.services.headscale;
  server-url = "head.pbsds.net";
  derpPort = 3478;
  inherit (lib) mkIf getExe;
in
{
  environment.systemPackages = mkIf cfg.enable [ cfg.package ];

  services.headscale = {
    enable  = true;
    address = "127.0.0.1";
    port    = 4987;

    # https://github.com/juanfont/headscale/blob/main/config-example.yaml
    # https://search.nixos.org/options?query=services.headscale.settings
    settings = {
      server_url = "https://${server-url}:443";
      logtail.enabled = false;
      log.level = "warn";

      # https://tailscale.com/kb/1054/dns
      dns_config.override_local_dns = true; # force clients to use our dns
      #dns_config.nameservers = [ "1.1.1.1" ];
      dns_config.magic_dns = true; # put our dns first in search
      dns_config.domains = [ "ts.pbsds.net" ]; # search domains to inject into clients
      dns_config.base_domain = "pbsds.net"; # clients become {hostname}.namespace.{base_domain}

      # List of IP prefixes to allocate tailaddresses from.
      ip_prefixes = [
        "100.64.0.0/10"
        "fd7a:115c:a1e0::/48"
      ];

      # DERP is a relay system that Tailscale uses when a direct connection cannot be established.
      # https://tailscale.com/blog/how-tailscale-works/#encrypted-tcp-relays-derp
      # headscale needs a list of DERP servers that can be presented to the clients.
      derp.server.enable = true; # run embedded DERP server
      derp.server.region_id = 999;
      derp.server.stun_listen_addr = "0.0.0.0:${toString derpPort}"; # UDP
      #derp.server.private_key_path # autogenerated if it's missing.
      #derp.urls = [] # List of externally available DERP maps
    };
  };

  systemd.services."headscale-provisioning" = mkIf cfg.enable {
    serviceConfig.Type = "oneshot";
    after = [ "headscale.service" ];
    wantedBy = [ "headscale.service" ];
    script = ''
      sleep 60 # Wait for headscale to be ready
      ${getExe cfg.package} namespaces create ts || true
    '';
  };

  # The DERP server
  networking.firewall.allowedUDPPorts = mkIf (cfg.enable && cfg.settings.derp.server.enable) [ derpPort ];

  # https reverse proxy

  networking.firewall.allowedTCPPorts = mkIf cfg.enable [ 80 443 ];

  services.nginx.enable = mkIf cfg.enable true;
  services.nginx.virtualHosts."${server-url}" = mkIf cfg.enable {
    forceSSL = true; # addSSL = true;
    enableACME = true; #useACMEHost = acmeDomain;
    locations."/" = {
      proxyPass = "http://localhost:${toString cfg.port}";
      proxyWebsockets = true;
    };
    #locations."/metrics".proxyPass = "http://${cfg.settings.metrics_listen_addr}/metrics";
  };

}
