{
  lib,
  config,
  pkgs,
  ...
}:
let
  cfg = config.khscodes.services.vault-agent;
  mkSubmodule =
    {
      options,
      description,
    }:
    lib.types.submoduleWith {
      description = description;
      shorthandOnlyDefinesConfig = true;
      modules = lib.toList { inherit options; };
    };
  restartUnits =
    svcs:
    lib.strings.concatStringsSep "\n" (
      lib.lists.map (svc: "systemctl restart ${lib.escapeShellArg svc}") svcs
    );
  reloadOrRestartUnits =
    svcs:
    lib.strings.concatStringsSep "\n" (
      lib.lists.map (svc: "systemctl reload-or-restart ${lib.escapeShellArg svc}") svcs
    );
  mapTemplate =
    template:
    let
      command = lib.getExe (
        pkgs.writeShellApplication {
          name = "restart-command";
          runtimeInputs = [ pkgs.systemd ];
          text = ''
            chown ${lib.escapeShellArg template.owner}:${lib.escapeShellArg template.group} ${lib.escapeShellArg template.destination}
            ${restartUnits template.restartUnits}
            ${reloadOrRestartUnits template.reloadOrRestartUnits}
            ${template.exec}
          '';
          meta = {
            mainProgram = "restart-command";
          };
        }
      );
    in
    {
      inherit (template) destination perms contents;
      exec = {
        command = command;
      };
    };
  settings = {
    vault = {
      address = cfg.vault.address;
    };
    auto_auth = {
      method = [
        {
          type = "approle";
          config = {
            mount_path = "auth/approle";
            role_id_file_path = cfg.vault.roleIdFilePath;
            secret_id_file_path = cfg.vault.secretIdFilePath;
            remove_secret_id_file_after_reading = false;
          };
        }
      ];
    };

    template_config = {
      exit_on_retry_failure = true;
      static_secret_render_interval = "10m";
      max_connections_per_host = 10;
      leases_renewal_threshold = 0.5;
    };
    template = lib.mkIf (cfg.templates != [ ]) (lib.lists.map mapTemplate cfg.templates);
  };
  unitsDependsOnAgent = lib.lists.unique (
    lib.lists.flatten (lib.lists.map (t: t.restartUnits ++ t.reloadOrRestartUnits) cfg.templates)
  );
in
{
  options.khscodes.services.vault-agent = {
    enable = lib.mkEnableOption "Enables the OpenBAO agent";
    package = lib.mkOption {
      type = lib.types.package;
      default = pkgs.openbao;
      defaultText = "pkgs.openbao";
    };
    vault = {
      address = lib.mkOption {
        type = lib.types.str;
        description = "Address of the Vault/OpenBAO service";
        default = "https://${config.khscodes.infrastructure.openbao.domain}";
      };
      roleIdFilePath = lib.mkOption {
        type = lib.types.str;
        description = "Location of the role id";
        default = "/var/lib/vault-agent/role-id";
      };
      secretIdFilePath = lib.mkOption {
        type = lib.types.str;
        description = "Location of the secret id";
        default = "/var/lib/vault-agent/secret-id";
      };
    };
    templates = lib.mkOption {
      default = [ ];
      type = lib.types.listOf (mkSubmodule {
        description = "List of templates to render";
        options = {
          contents = lib.mkOption {
            type = lib.types.str;
            description = "Contents of the template (.ctmpl)";
          };
          destination = lib.mkOption {
            type = lib.types.str;
            description = "Destination file for the template";
          };
          restartUnits = lib.mkOption {
            type = lib.types.listOf lib.types.str;
            description = "List of systemd units to restart when template changes";
            default = [ ];
          };
          reloadOrRestartUnits = lib.mkOption {
            type = lib.types.listOf lib.types.str;
            description = "List of systemd units to reload-or-restart when template changes";
            default = [ ];
          };
          perms = lib.mkOption {
            type = lib.types.str;
            description = "Permissions of the generated file, by default will only be readable by root";
            default = "0600";
          };
          owner = lib.mkOption {
            type = lib.types.str;
            description = "Owner (user) of the generated file";
            default = "root";
          };
          group = lib.mkOption {
            type = lib.types.str;
            description = "Group of the generated file";
            default = "root";
          };
          exec = lib.mkOption {
            type = lib.types.lines;
            default = '''';
            description = "Command to execute when template renders new data";
          };
        };
      });
    };
  };

  config = lib.mkIf cfg.enable {
    services.vault-agent.instances.openbao = {
      inherit settings;
      enable = true;
      package = cfg.package;
      user = "root";
      group = "root";
    };
    systemd.services."vault-agent-openbao" = {
      before = unitsDependsOnAgent;
      wantedBy = unitsDependsOnAgent;
      unitConfig = {
        ConditionPathExists = [
          cfg.vault.secretIdFilePath
          cfg.vault.roleIdFilePath
        ];
      };
    };
  };
}
