{
  config,
  lib,
  pkgs,
  ...
}:
with lib; let
  cfg = config.services.rclone-serve;

  makeNameSafe = name: builtins.replaceStrings ["/"] ["-"] name;

  daemonService = serve_config:
    lib.mkMerge [
      {
        wantedBy = ["multi-user.target"];

        after = ["network.target"];
        wants = ["network.target"];

        serviceConfig = {
          Type = "simple";
          Restart = "on-failure";
          RestartSec = "5s";

          User =
            if serve_config.user != null
            then "${serve_config.user}"
            else "root";

          ExecStart = "${pkgs.rclone}/bin/rclone serve ${serve_config.type} ${serve_config.remote} ${
            lib.concatStringsSep " " serve_config.extraArgs
          }";
        };
      }
      serve_config.serviceConfig
    ];
in {
  options = {
    services.rclone-serve = {
      enable = mkOption {
        type = types.bool;
        default = false;
      };

      remotes = mkOption {
        type = types.listOf (types.submodule {
          options = {
            remote = mkOption {type = types.str;};
            type = mkOption {type = types.str;};
            user = mkOption {type = types.str;};
            serviceConfig = mkOption {type = types.attrs;};

            extraArgs = mkOption {type = types.listOf types.str;};
          };
        });
        default = [];
      };
    };
  };

  config = mkMerge [
    (mkIf (cfg.enable && cfg.remotes != []) {
      systemd.services = listToAttrs (map (remote: {
          name = "rclone-serve-${makeNameSafe remote.type}-${
            makeNameSafe remote.remote
          }";
          value = daemonService remote;
        })
        cfg.remotes);
    })
  ];
}