{
  config,
  lib,
  pkgs,
  ...
}:
let
  inherit (lib)
    mkIf
    mkEnableOption
    mkOption
    concatLists
    concatStringsSep
    ;
  inherit (lib.types)
    str
    listOf
    enum
    bool
    ;
  inherit (lib.my) getExe;
  cfg = config.modules.services.tailscale;
in
{
  options.modules.services.tailscale = {
    enable = mkEnableOption "Tailscale";

    server = mkOption {
      type = str;
      default = "https://hs.ccnlc.eu";
      description = "The coordination server tailscale should be using.";
    };

    isExitNode = mkOption {
      type = bool;
      default = false;
      description = "Enable if node should serve advertise itself as an exit node.";
    };

    tags = mkOption {
      type = listOf (enum [
        "client"
        "server"
      ]);
      default = [ ];
      apply = map (e: "tag:${e}");
    };

    defaultFlags = mkOption {
      type = listOf str;
      default = [ "--ssh" ];
    };

    extraFlags = mkOption {
      type = listOf str;
      default = [ ];
    };

    systemTray = mkOption {
      type = bool;
      default = config.modules.system.roles.desktop.enable;
      description = "Display a system tray icon to interact with tailscale.";
    };
  };

  config = mkIf cfg.enable {
    services.tailscale = {
      enable = true;
      extraUpFlags = concatLists [
        cfg.defaultFlags
        cfg.extraFlags
        (
          mkIf cfg.tags != [ ] [
            "--advertise-tags"
            (concatStringsSep "," cfg.tags)
          ]
        )
        (mkIf cfg.server [
          "--login-server"
          cfg.server
        ])
      ];
      useRoutingFeatures = mkIf cfg.isExitNode "server";
    };

    systemd.user.services.tailscale-system-tray = mkIf cfg.systemTray {
      description = "tailscale system tray";
      wantedBy = [ "graphical-session.target" ];
      after = [ "graphical-session.target" ];
      path = with pkgs; [
        polkit
        tailscale
      ];
      serviceConfig = {
        Type = "simple";
        ExecStart = getExe pkgs.tail-tray;
        Restart = "on-failure";
        RestartSec = 1;
        TimeoutStopSec = 10;
        IPAddressDeny = "any";
        NoNewPrivileges = true;
        ProtectClock = true;
        ProtectKernelTunables = true;
        ProtectKernelModules = true;
        ProtectKernelLogs = true;
        SystemCallFilter = "~@clock @cpu-emulation @debug @obsolete @module @mount @raw-io @reboot @swap";
        #  ProtectControlGroups = true;
        #RestrictNamespaces = true;
        LockPersonality = true;
        MemoryDenyWriteExecute = true;
        RestrictRealtime = true;
        RestrictSUIDSGID = true;
      };
    };
  };
}