{ config, lib, pkgs, ... }:

{
  options.c3d2.audioServer = {
    enable = lib.mkEnableOption "Enable PulseAudio and Bluetooth sinks";
  };

  config = lib.mkIf config.c3d2.audioServer.enable {
    boot.kernelPackages = lib.mkOverride 900 pkgs.linuxPackages-rt_latest;

    environment.systemPackages = with pkgs; [
      mpd
      mpv
      ncmpcpp
      ncpamixer
      pulseaudio # required for pactl
      somafm-cli
    ];

    hardware = {
      bluetooth.settings = {
        Policy.AutoEnable = true;
        General.DiscoverableTimeout = 0;
      };

      pulseaudio = {
        enable = !config.services.pipewire.pulse.enable;
        systemWide = true;
        tcp = {
          enable = true;
          anonymousClients.allowedIpRanges = [
            "127.0.0.0/8"
            "::1/128"
            "fd23:42:c3d2:500::/56"
            "172.22.99.0/24"
            "172.20.72.0/21"
            "2a00:8180:2c00:200::/56"
            "2a0f:5382:acab:1400::/56"
          ];
        };
        zeroconf.publish.enable = true;
        package = (pkgs.pulseaudio.override {
          bluetoothSupport = true;
          advancedBluetoothCodecs = true;
          zeroconfSupport = true;
        }).overrideAttrs (_: {
          # one test times out
          doCheck = false;
        });
      };
    };

    networking.firewall = {
      allowedTCPPorts = [
        80 # ledfx
        4713 # pulseaudio/pipewire network sync
      ];
      allowedUDPPorts = [
        5353 # mdns
      ];
    };

    nixpkgs.overlays = [
      (final: prev: {
        python3 = prev.python3.override {
          packageOverrides = python-final: python-prev: {
            # avoid dependency on x11 libraries
            samplerate = python-prev.samplerate.overrideAttrs (_: {
              dontUseSetuptoolsCheck = true;
            });
          };
        };
        python3Packages = final.python3.pkgs;
      })
    ];

    security = {
      polkit.extraConfig = /* javascript */ ''
        # https://www.reddit.com/r/voidlinux/comments/o74i76/comment/h2z9u11/?utm_source=reddit&utm_medium=web2x&context=3
        polkit.addRule(function(action, subject) {
          if (action.id == "org.freedesktop.RealtimeKit1.acquire-high-priority"
            || action.id == "org.freedesktop.RealtimeKit1.acquire-real-time") {
            return polkit.Result.YES;
          }
        });
      '';
      rtkit.enable = true;
    };

    services.pipewire = {
      enable = true;
      alsa.enable = true; # required for ledfx
      config.pipewire-pulse =
        let
          default-pipewire-pulse = lib.importJSON (pkgs.path + "/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json");
        in
        #      _____ _______ ____  _____
          #   / ____|__   __/ __ \|  __ \
          #  | (___    | | | |  | | |__) |
          #   \___ \   | | | |  | |  ___/
          #   ____) |  | | | |__| | |
          #  |_____/   |_|  \____/|_|
          #
          # errors such as:
          # mod.zeroconf-publish: error id:47 seq:349 res:-2 (No such file or directory): enum params id:16 (Spa:Enum:ParamId:ProcessLatency) failed
          # are harmless and can be ignored. You most likely want to restart your local avahi-daemon: sudo systemctl restart avahi-daemon
        default-pipewire-pulse // {
          "context.exec" = default-pipewire-pulse."context.exec" ++ [
            {
              "path" = "pactl";
              "args" = "load-module module-zeroconf-publish";
            }
          ];
          "pulse.properties" = {
            "auth-ip-acl" = [
              "127.0.0.0/8"
              "::1/128"
              "fd23:42:c3d2:500::/56"
              "172.22.99.0/24"
              "172.20.72.0/21"
              "2a00:8180:2c00:200::/56"
              "2a0f:5382:acab:1400::/56"
            ];
            "server.address" = [
              "unix:native"
              "tcp:4713"
            ];
          };
        };
      pulse.enable = true;
    };

    # tell Avahi to publish services like Pipewire/PulseAudio
    services.avahi = {
      enable = true;
      nssmdns = true;
      publish = {
        enable = true;
        addresses = true;
        userServices = true;
      };
    };

    sound.enable = true;

    system.activationScripts.enableLingering = lib.optionalString config.services.pipewire.pulse.enable (''
      rm -r /var/lib/systemd/linger
      mkdir /var/lib/systemd/linger
    '' + lib.optionalString config.c3d2.k-ot.enable ''
      touch /var/lib/systemd/linger/k-ot
    '');

    systemd = {
      services.bluetooth-agent = lib.mkIf config.hardware.bluetooth.enable {
        description = "Allow anyone to pair via Bluetooth";
        wantedBy = [ "multi-user.target" ];
        requires = [ "bluetooth.target" ];
        after = [ "bluetooth.service" ];
        serviceConfig = {
          Type = "simple";
          ExecStart = "${pkgs.bluez-tools}/bin/bt-agent -c NoInputNoOutput";
          Restart = "on-failure";
          RestartSec = 60;
        };
      };
      user.services = {
        ledfx = {
          after = [ "pipewire.target" ];
          wantedBy = [ "default.target" ];
          serviceConfig = {
            ExecStart = "${pkgs.ledfx}/bin/ledfx";
          };
        };
        pipewire-pulse.enable = true;
      };
    };

    users = {
      groups.pulse-access = { };
      users.k-ot = lib.mkIf config.c3d2.k-ot.enable {
        extraGroups = [
          "pipewire"
          "pulse-access" # required for system wide pulseaudio
          "rtkit"
        ];
        packages = with pkgs; [
          (yt-dlp.override { withAlias = true; })
        ];
      };
    };
  };
}
