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

with lib;
let
  cfg = config.fudo.pricebot;

  botJobOpts = { name, ... }: {
    options = with types; {
      mattermost-channel-id = mkOption {
        type = str;
        description = "Channel ID in which to post updates.";
      };

      currency = mkOption {
        type = str;
        description = "Cryptocurrency to watch for price changes.";
        default = name;
      };

      notify-user = mkOption {
        type = str;
        description = "Mattermost username to notify of important events.";
      };
    };
  };

in {
  options.fudo.pricebot = with types; {
    enable = mkEnableOption "Enable PriceBot.";

    exchange-host = mkOption {
      type = str;
      description = "Coinbase Pro host to contact for prices.";
      default = "api.exchange.coinbase.com";
    };

    mattermost-url = mkOption {
      type = str;
      description = "Mattermost host on which to emit price notifications.";
    };

    mattermost-auth-token-file = mkOption {
      type = str;
      description =
        "File (on the local system) in which to find the auth token to pass to Mattermost.";
    };

    monitors = mkOption {
      type = attrsOf (submodule botJobOpts);
      description = "Map of currency to notify options.";
      default = { };
    };
  };

  config = {
    systemd.services = mapAttrs' (currency: opts:
      nameValuePair "pricebot-${currency}" {
        description = "PriceBot for watching and reporting ${currency} prices";
        wantedBy = [ "multi-user.target" ];
        after = [ "network-online.target" ];
        environment = {
          PRICEBOT_EXCHANGE_HOST = cfg.exchange-host;
          PRICEBOT_BEBOT_URL = cfg.mattermost-url;
          PRICEBOT_BEBOT_CHANNEL_ID = opts.mattermost-channel-id;
          PRICEBOT_CURRENCY = opts.currency;
          PRICEBOT_NOTIFY_USER = opts.notify-user;
        };
        serviceConfig = {
          ExecStart = pkgs.writeShellScript "launch-pricebot-${currency}.sh" ''
            ${pricebot}/bin/pricebot --bebot-auth-token-file=$CREDENTIALS_DIRECTORY/auth.token
          '';
          DynamicUser = true;
          PrivateTmp = true;
          PrivateDevices = true;
          ProtectSystem = "strict";
          ProtectControlGroups = true;
          ProtectKernelTunables = true;
          ProtectKernelModules = true;
          ProtectHostname = true;
          ProtectHome = true;
          ProtectClock = true;
          ProtectKernelLogs = true;
          Restart = "always";
          StandardOutput = "journal";
          LoadCredential = "auth.token:${cfg.mattermost-auth-token-file}";
        };
      }) cfg.monitors;
  };
}