{
  config,
  lib,
  ...
}:
let
  cfg = config.khscodes.infrastructure.vault-loki-sender;
  fqdn = config.khscodes.networking.fqdn;
  vaultRoleName = config.khscodes.infrastructure.vault-server-approle.role_name;
  client_key = "/var/lib/alloy/loki.key";
  client_cert = "/var/lib/alloy/loki.cert";
in
{
  options.khscodes.infrastructure.vault-loki-sender = {
    enable = lib.mkEnableOption "Configures the server approle to allow sending data to loki";
    terranixBackendName = lib.mkOption {
      type = lib.types.str;
      description = "This should only be configured for the server hosting loki, to allow setting up dependencies in terraform";
      default = "loki-mtls";
    };
    extraFiles = lib.mkOption {
      type = lib.types.listOf lib.types.path;
      description = "Extra alloy files to deploy";
      default = [ ];
    };
    extraGroups = lib.mkOption {
      type = lib.types.listOf lib.types.str;
      description = "Extra groups to add to alloy to allow reading log files";
      default = [ ];
    };
  };

  config = lib.mkIf cfg.enable {
    khscodes.infrastructure.vault-server-approle = {
      enable = true;
      policy = {
        "loki-mtls" = {
          capabilities = [ "read" ];
        };
        "loki-mtls/issue/${fqdn}" = {
          capabilities = [
            "create"
            "update"
          ];
        };
      };
      stageModules = [
        (
          { ... }:
          {
            khscodes.vault.pki_secret_backend_role."${vaultRoleName}-loki" = {
              name = vaultRoleName;
              backend = cfg.terranixBackendName;
              allowed_domains = [ fqdn ];
              allow_bare_domains = true;
              enforce_hostnames = true;
              server_flag = false;
              client_flag = true;
            };
          }
        )
      ];
    };
    khscodes.services.vault-agent.templates = [
      {
        contents = ''
          {{- with pkiCert "loki-mtls/issue/${fqdn}" "common_name=${fqdn}" -}}
          {{ .Key }}
          {{ .Cert }}
          {{ .CA }}
          {{ .Key | writeToFile "${client_key}" "${config.khscodes.services.alloy.user}" "${config.khscodes.services.alloy.group}" "0600" }}
          {{ .Cert | writeToFile "${client_cert}" "${config.khscodes.services.alloy.user}" "${config.khscodes.services.alloy.group}" "0644" }}
          {{- end -}}
        '';
        destination = "/var/lib/alloy/loki.cache";
        owner = "alloy";
        group = "alloy";
        perms = "0600";
        # Alloy doesn't seem to reload the certificates when using just reload
        # so restart the unit.
        restartUnits = [ "alloy.service" ];
      }
    ];
    khscodes.services.alloy = {
      enable = true;
      environment = {
        LOKI_CLIENT_KEY = client_key;
        LOKI_CLIENT_CERT = client_cert;
      };
    };
    users.users.alloy.extraGroups = cfg.extraGroups;
    environment.etc =
      {
        "alloy/loki.alloy" = {
          source = ./loki.alloy;
        };
        "alloy/loki_endpoint.alloy" = {
          source = ./loki_endpoint.alloy;
        };
      }
      // (lib.listToAttrs (
        lib.lists.map (f: {
          name = "alloy/${builtins.baseNameOf f}";
          value = {
            source = f;
          };
        }) cfg.extraFiles
      ));
  };
}
