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

let
  cfg = config.programs.whois;

  configText =
    lib.concatStringsSep "\n" (
      [
        "# Generated by NixOS."
        "# See whois.conf(5) for the file format."
      ]
      ++ map (entry: "${entry.pattern} ${entry.server}") cfg.settings
    )
    + "\n";
in

{
  options.programs.whois = {
    enable = lib.mkEnableOption "whois, an intelligent WHOIS client";

    package = lib.mkPackageOption pkgs "whois" { };

    settings = lib.mkOption {
      type = lib.types.listOf (
        lib.types.submodule {
          options = {
            pattern = lib.mkOption {
              type = lib.types.str;
              example = "\\.dn42$";
              description = ''
                Case-insensitive extended regular expression used to match the
                WHOIS object identifier.
              '';
            };

            server = lib.mkOption {
              type = lib.types.str;
              example = "whois.dn42";
              description = ''
                WHOIS server to use when {option}`pattern` matches.
              '';
            };
          };
        }
      );
      default = [ ];
      example = lib.literalExpression ''
        [
          {
            pattern = "\\.dn42$";
            server = "whois.dn42";
          }
          {
            pattern = "\\-DN42$";
            server = "whois.dn42";
          }
          {
            pattern = "^as424242[0-9]{4}$";
            server = "whois.dn42";
          }
          {
            pattern = "^172\\.2[0-3]\\.[0-9]{1,3}\\.[0-9]{1,3}(/(1[56789]|2[0-9]|3[012]))?$";
            server = "whois.dn42";
          }
        ]
      '';
      description = ''
        WHOIS configuration entries written to {file}`/etc/whois.conf`.

        Entries are written in the declared order, which matters when multiple
        patterns may match the same query.
      '';
    };

  };

  config = lib.mkIf cfg.enable {
    environment.systemPackages = [ cfg.package ];

    environment.etc."whois.conf".text = configText;
  };

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