{ config, lib, ... }:
let
  inherit (lib)
    mkIf
    mkOption
    mkEnableOption
    listToAttrs
    ;
  inherit (lib.types)
    enum
    listOf
    submodule
    nonEmptyStr
    str
    bool
    ;
  inherit (lib.my) mkPortOption slugify;

  cfg = config.modules.server.rsync-daemon;
in
{
  options.modules.server.rsync-daemon = {
    enable = mkEnableOption "rsync daemon";
    openFirewall = mkOption {
      type = bool;
      default = false;
      description = "Whether to open the firewall";
    };
    port = mkPortOption 9523 "rsyncd";
    address = mkOption {
      type = nonEmptyStr;
      default = "0.0.0.0";
      description = "The address rsyncd should listen on";
    };
    location = mkOption {
      type = nonEmptyStr;
      default = "/var/lib/rsync-backups";
    };

    modules = mkOption {
      default = { };
      type = listOf (submodule {
        options = {
          mode = mkOption {
            type = enum [
              "read"
              "write"
              "both"
            ];
            default = "read";
          };
          name = mkOption {
            type = nonEmptyStr;
            default = "";
            description = "MANDATORY: The name of the module";
          };
          comment = mkOption {
            type = str;
            default = "";
            description = "A descriptive comment for the module.";
          };
        };
      });
    };
  };

  config = mkIf cfg.enable {
    networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];

    systemd.tmpfiles.settings."10-nginx-daemon" = listToAttrs (
      map (mod: {
        name = "${cfg.location}/${slugify mod.name}";
        value.d = {
          group = "nogroup";
          mode = "0777";
          user = "nobody";
        };
      }) cfg.modules
    );

    modules.fixes.services.rsyncd = {
      enable = true;
      socketActivated = true;
      settings = {
        globalSection = {
          inherit (cfg) port address;
        };
        sections = listToAttrs (
          map (mod: {
            inherit (mod) name;
            value = {
              inherit (mod) comment;
              path = "${cfg.location}/${slugify mod.name}";
              "read only" = mod.mode == "read" || mod.mode == "both";
              "write only" = mod.mode == "write" || mod.mode == "both";
            };
          }) cfg.modules
        );
      };
    };
  };
}