{
  pkgs,
  config,
  lib,
  ...
}:
let
  inherit (lib) types mkOption mkDefault;
  yaml = pkgs.formats.yaml { };
in
{
  options = {
    services.prometheus = {
      extraExporters = mkOption {
        default = { };
        type = types.attrsOf (
          types.submodule {
            options = {
              port = mkOption {
                type = types.int;
                description = "The port on which this exporter listens.";
              };
              listenAddress = mkOption {
                type = types.str;
                default = "127.0.0.1";
                description = "Address to listen on.";
              };
              serviceOpts = mkOption {
                type = types.attrs;
                description = "An attrset to be merged with the exporter's systemd service.";
              };
            };
          }
        );
      };
    };

    services.victoriametrics.scrapeConfigs = mkOption {
      type = types.attrsOf (
        types.submodule (
          { name, self, ... }:
          {
            options = {
              job_name = mkOption {
                type = types.str;
                default = name;
              };

              extraSettings = mkOption {
                inherit (pkgs.formats.yaml { }) type;
                description = ''
                  Other settings to set for this scrape config.
                '';
                default = { };
              };

              targets = mkOption {
                type = types.listOf types.str;
                description = lib.mdDoc ''
                  Addresses scrape targets for this config listen on.

                  Shortcut for `static_configs = lib.singleton {targets = [<targets>];}`
                '';
                default = [ ];
              };

              static_configs = mkOption {
                default = [ ];
                type = types.listOf (
                  types.submodule {
                    options = {
                      targets = mkOption {
                        type = types.listOf types.str;
                        description = lib.mdDoc ''
                          The addresses scrape targets for this config listen on.

                          Must in `listenAddress:port` format.
                        '';
                      };
                      labels = mkOption {
                        type = types.attrsOf types.str;
                        description = lib.mdDoc ''
                          Labels to apply to all targets defined for this static config.
                        '';
                        default = { };
                      };
                    };
                  }
                );
              };
            };
          }
        )
      );
    };
  };

  config = {
    systemd.services = lib.mkMerge [
      (lib.mapAttrs' (
        name: exporter:
        lib.nameValuePair "prometheus-${name}-exporter" (
          lib.mkMerge [
            {
              # Shamelessly copied from upstream because the upstream
              # module is an intractable mess
              wantedBy = [ "multi-user.target" ];
              after = [ "network.target" ];
              serviceConfig.Restart = mkDefault "always";
              serviceConfig.PrivateTmp = mkDefault true;
              serviceConfig.WorkingDirectory = mkDefault /tmp;
              serviceConfig.DynamicUser = mkDefault true;
              # Hardening
              serviceConfig.CapabilityBoundingSet = mkDefault [ "" ];
              serviceConfig.DeviceAllow = [ "" ];
              serviceConfig.LockPersonality = true;
              serviceConfig.MemoryDenyWriteExecute = true;
              serviceConfig.NoNewPrivileges = true;
              serviceConfig.PrivateDevices = mkDefault true;
              serviceConfig.ProtectClock = mkDefault true;
              serviceConfig.ProtectControlGroups = true;
              serviceConfig.ProtectHome = true;
              serviceConfig.ProtectHostname = true;
              serviceConfig.ProtectKernelLogs = true;
              serviceConfig.ProtectKernelModules = true;
              serviceConfig.ProtectKernelTunables = true;
              serviceConfig.ProtectSystem = mkDefault "strict";
              serviceConfig.RemoveIPC = true;
              serviceConfig.RestrictAddressFamilies = [
                "AF_INET"
                "AF_INET6"
              ];
              serviceConfig.RestrictNamespaces = true;
              serviceConfig.RestrictRealtime = true;
              serviceConfig.RestrictSUIDSGID = true;
              serviceConfig.SystemCallArchitectures = "native";
              serviceConfig.UMask = "0077";
            }
            exporter.serviceOpts
          ]
        )
      ) config.services.prometheus.extraExporters)

      {
        vmagent-scrape-exporters =
          let
            listenAddress = config.services.victoriametrics.listenAddress;
            vmAddr = (lib.optionalString (lib.hasPrefix ":" listenAddress) "127.0.0.1") + listenAddress;
            promscrape = yaml.generate "prometheus.yml" {
              scrape_configs = lib.mapAttrsToList (
                _: scrape:
                lib.recursiveUpdate {
                  inherit (scrape) job_name;
                  static_configs =
                    scrape.static_configs
                    ++ lib.optional (scrape.targets != [ ]) { targets = scrape.targets; };
                } scrape.extraSettings
              ) config.services.victoriametrics.scrapeConfigs;
            };
          in
          {
            enable = true;
            path = [ pkgs.victoriametrics ];
            wantedBy = [ "multi-user.target" ];
            after = [
              "network.target"
              "victoriametrics.service"
            ];
            serviceConfig = {
              ExecStart = [
                (lib.concatStringsSep " " [
                  "${pkgs.victoriametrics}/bin/vmagent"
                  "-promscrape.config=${promscrape}"
                  "-remoteWrite.url=http://${vmAddr}/api/v1/write"
                  "-remoteWrite.tmpDataPath=%t/vmagent"
                ])
              ];
              SupplementaryGroups = "metrics";

              DynamicUser = true;
              RuntimeDirectory = "vmagent";
              CapabilityBoundingSet = [ "" ];
              DeviceAllow = [ "" ];
              LockPersonality = true;
              MemoryDenyWriteExecute = true;
              NoNewPrivileges = true;
              PrivateDevices = true;
              ProtectClock = true;
              ProtectControlGroups = true;
              ProtectHome = true;
              ProtectHostname = true;
              ProtectKernelLogs = true;
              ProtectKernelModules = true;
              ProtectKernelTunables = true;
              ProtectSystem = "strict";
              RemoveIPC = true;
              RestrictAddressFamilies = [
                "AF_INET"
                "AF_INET6"
              ];
              RestrictNamespaces = true;
              RestrictRealtime = true;
              RestrictSUIDSGID = true;
              SystemCallArchitectures = "native";
              UMask = "0077";
            };
          };
      }
    ];

    users.groups.metrics = { };

    services.victoriametrics.scrapeConfigs =
      let
        allExporters = lib.mapAttrs (name: exporter: { inherit (exporter) listenAddress port; }) (
          (lib.filterAttrs (
            name: exporter:
            # A bunch of deprecated exporters that need to be ignored
            !(builtins.elem name [
              "blackbox"
              "minio"
              "tor"
              "unifi-poller"
            ])
            && builtins.isAttrs exporter
            && exporter.enable
          ) config.services.prometheus.exporters)
          // config.services.prometheus.extraExporters
        );
      in
      lib.mapAttrs (_: exporter: {
        targets = [ "${exporter.listenAddress}:${toString exporter.port}" ];
      }) allExporters;
  };
}