{
  config,
  lib,
  inputs,
  pkgs,
  ...
}:
let
  cfg = config.khscodes.infrastructure.provisioning;
  provisioning = {
    modules = lib.mkOption {
      type = lib.types.listOf lib.types.anything;
      description = "Modules used to bring up the needed resources";
      default = [ ];
    };
    secretsSource = lib.mkOption {
      type = lib.types.enum [
        "vault"
        "bitwarden"
      ];
      description = "Where to get the secrets for the provisioning from";
      default = "vault";
    };
    endpoints = lib.mkOption {
      type = lib.types.listOf (
        lib.types.enum [
          "openstack"
          "aws"
          "unifi"
          "hcloud"
          "cloudflare"
          "vault"
          "authentik"
        ]
      );
      description = "Needed endpoints to be used during provisioning";
      default = [ ];
    };
  };
in
{
  options.khscodes.infrastructure.provisioning = {
    pre = provisioning;
    post = provisioning;
    instanceUserData = lib.mkOption {
      type = lib.types.str;
      description = "User data that should be added to the instance during provisioning";
      default = "";
    };
    preConfig = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      description = "The generated config for the pre provisioning, if any was specified";
    };
    preImageUsername = lib.mkOption {
      type = lib.types.str;
      description = "The username for the image being deployed before being swapped for NixOS";
      default = "root";
    };
    postConfig = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      description = "The generated config for the post provisioning, if any was specified";
    };
  };

  config = {
    khscodes.infrastructure.provisioning.preConfig =
      if lib.lists.length cfg.pre.modules > 0 then
        inputs.terranix.lib.terranixConfiguration {
          system = pkgs.hostPlatform.system;
          modules = cfg.pre.modules;
        }
      else
        null;
    khscodes.infrastructure.provisioning.postConfig =
      if lib.lists.length cfg.post.modules > 0 then
        inputs.terranix.lib.terranixConfiguration {
          system = pkgs.hostPlatform.system;
          modules = cfg.post.modules;
        }
      else
        null;
  };
}
