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

with lib;

let
  cfg = config.services.gmediarender;
in
{
  options.services.gmediarender = {
    enable = mkEnableOption "the gmediarender DLNA renderer";

    audioDevice = mkOption {
      type = types.nullOr types.str;
      default = null;
      description = ''
        The audio device to use.
      '';
    };

    audioSink = mkOption {
      type = types.nullOr types.str;
      default = null;
      description = ''
        The audio sink to use.
      '';
    };

    friendlyName = mkOption {
      type = types.nullOr types.str;
      default = null;
      description = ''
        A "friendly name" for identifying the endpoint.
      '';
    };

    initialVolume = mkOption {
      type = types.nullOr types.int;
      default = 0;
      description = ''
        A default volume attenuation (in dB) for the endpoint.
      '';
    };

    package = mkPackageOption pkgs "gmediarender" {
      default = "gmrender-resurrect";
    };

    port = mkOption {
      type = types.nullOr types.port;
      default = null;
      description = "Port that will be used to accept client connections.";
    };

    uuid = mkOption {
      type = types.nullOr types.str;
      default = null;
      description = ''
        A UUID for uniquely identifying the endpoint.  If you have
        multiple renderers on your network, you MUST set this.
      '';
    };
  };

  config = mkIf cfg.enable {
    systemd = {
      services.gmediarender = {
        wants = [ "network-online.target" ];
        after = [ "network-online.target" ];
        wantedBy = [ "multi-user.target" ];
        description = "gmediarender server daemon";
        environment = {
          XDG_CACHE_HOME = "%t/gmediarender";
        };
        serviceConfig = {
          DynamicUser = true;
          User = "gmediarender";
          Group = "gmediarender";
          SupplementaryGroups = [ "audio" ];
          ExecStart =
            "${cfg.package}/bin/gmediarender " +
            optionalString (cfg.audioDevice != null) ("--gstout-audiodevice=${utils.escapeSystemdExecArg cfg.audioDevice} ") +
            optionalString (cfg.audioSink != null) ("--gstout-audiosink=${utils.escapeSystemdExecArg cfg.audioSink} ") +
            optionalString (cfg.friendlyName != null) ("--friendly-name=${utils.escapeSystemdExecArg cfg.friendlyName} ") +
            optionalString (cfg.initialVolume != 0) ("--initial-volume=${toString cfg.initialVolume} ") +
            optionalString (cfg.port != null) ("--port=${toString cfg.port} ") +
            optionalString (cfg.uuid != null) ("--uuid=${utils.escapeSystemdExecArg cfg.uuid} ");
          Restart = "always";
          RuntimeDirectory = "gmediarender";

          # Security options:
          CapabilityBoundingSet = "";
          LockPersonality = true;
          MemoryDenyWriteExecute = true;
          NoNewPrivileges = true;
          # PrivateDevices = true;
          PrivateTmp = true;
          PrivateUsers = true;
          ProcSubset = "pid";
          ProtectClock = true;
          ProtectControlGroups = true;
          ProtectHome = true;
          ProtectHostname = true;
          ProtectKernelLogs = true;
          ProtectKernelModules = true;
          ProtectKernelTunables = true;
          ProtectProc = "invisible";
          RestrictNamespaces = true;
          RestrictRealtime = true;
          RestrictSUIDSGID = true;
          SystemCallArchitectures = "native";
          SystemCallFilter = [ "@system-service" "~@privileged" ];
          UMask = 066;
        };
      };
    };
  };
}
