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

with lib;

let
  cfg = config.services.rss2email;
in {

  ###### interface

  options = {

    services.rss2email = {

      enable = mkOption {
        type = types.bool;
        default = false;
        description = "Whether to enable rss2email.";
      };

      to = mkOption {
        type = types.str;
        description = "Mail address to which to send emails";
      };

      interval = mkOption {
        type = types.str;
        default = "12h";
        description = "How often to check the feeds, in systemd interval format";
      };

      config = mkOption {
        type = with types; attrsOf (oneOf [ str int bool ]);
        default = {};
        description = ''
          The configuration to give rss2email.

          Default will use system-wide `sendmail` to send the
          email. This is rss2email's default when running
          `r2e new`.

          This set contains key-value associations that will be set in the
          `[DEFAULT]` block along with the
          `to` parameter.

          See `man r2e` for more information on which
          parameters are accepted.
        '';
      };

      feeds = mkOption {
        description = "The feeds to watch.";
        type = types.attrsOf (types.submodule {
          options = {
            url = mkOption {
              type = types.str;
              description = "The URL at which to fetch the feed.";
            };

            to = mkOption {
              type = with types; nullOr str;
              default = null;
              description = ''
                Email address to which to send feed items.

                If `null`, this will not be set in the
                configuration file, and rss2email will make it default to
                `rss2email.to`.
              '';
            };
          };
        });
      };
    };

  };


  ###### implementation

  config = mkIf cfg.enable {
    users.groups = {
      rss2email.gid = config.ids.gids.rss2email;
    };

    users.users = {
      rss2email = {
        description = "rss2email user";
        uid = config.ids.uids.rss2email;
        group = "rss2email";
      };
    };

    environment.systemPackages = with pkgs; [ rss2email ];

    services.rss2email.config.to = cfg.to;

    systemd.tmpfiles.settings."10-rss2email"."/var/rss2email".d = {
      user = "rss2email";
      group = "rss2email";
      mode = "0700";
    };

    systemd.services.rss2email = let
      conf = pkgs.writeText "rss2email.cfg" (lib.generators.toINI {} ({
          DEFAULT = cfg.config;
        } // lib.mapAttrs' (name: feed: nameValuePair "feed.${name}" (
          { inherit (feed) url; } //
          lib.optionalAttrs (feed.to != null) { inherit (feed) to; }
        )) cfg.feeds
      ));
    in
    {
      preStart = ''
        if [ ! -f /var/rss2email/db.json ]; then
          echo '{"version":2,"feeds":[]}' > /var/rss2email/db.json
        fi
      '';
      path = [ pkgs.system-sendmail ];
      serviceConfig = {
        ExecStart =
          "${pkgs.rss2email}/bin/r2e -c ${conf} -d /var/rss2email/db.json run";
        User = "rss2email";
      };
    };

    systemd.timers.rss2email = {
      partOf = [ "rss2email.service" ];
      wantedBy = [ "timers.target" ];
      timerConfig.OnBootSec = "0";
      timerConfig.OnUnitActiveSec = cfg.interval;
    };
  };

  meta.maintainers = with lib.maintainers; [ ekleog ];
}
