{
  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";
    };
  };
  usesEndpoint =
    search: endpoint: config:
    if lib.strings.hasInfix search (builtins.readFile config) then [ endpoint ] else [ ];
  endpointsMaps = [
    {
      search = "cloudflare/cloudflare";
      endpoint = "cloudflare";
    }
    {
      search = "hetznercloud/hcloud";
      endpoint = "hcloud";
    }
    {
      search = "terraform-provider-openstack/openstack";
      endpoint = "openstack";
    }
    {
      search = "paultyng/unifi";
      endpoint = "unifi";
    }
    {
      search = "hashicorp/vault";
      endpoint = "vault";
    }
    {
      search = ".r2.cloudflarestorage.com";
      endpoint = "aws";
    }
  ];
  endpointsUsed =
    config:
    if config == null then
      [ ]
    else
      lib.lists.flatten (lib.lists.map (c: usesEndpoint c.search c.endpoint config) endpointsMaps);
  preConfig =
    if lib.lists.length cfg.pre.modules > 0 then
      inputs.terranix.lib.terranixConfiguration {
        system = pkgs.hostPlatform.system;
        modules = cfg.pre.modules;
        extraArgs = { inherit lib inputs; };
      }
    else
      null;
  preEndpoints = endpointsUsed preConfig;
  postConfig =
    if lib.lists.length cfg.post.modules > 0 then
      inputs.terranix.lib.terranixConfiguration {
        system = pkgs.hostPlatform.system;
        modules = cfg.post.modules;
        extraArgs = { inherit lib inputs; };
      }
    else
      null;
  postEndpoints = endpointsUsed postConfig;
in
{
  options.khscodes.infrastructure.provisioning = {
    pre = provisioning;
    post = provisioning;
    instanceUserData = lib.mkOption {
      type = (pkgs.formats.json { }).type;
      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";
    };
    preEndpoints = lib.mkOption {
      type = lib.types.listOf (
        lib.types.enum [
          "openstack"
          "aws"
          "unifi"
          "hcloud"
          "cloudflare"
          "vault"
        ]
      );
      description = "Needed endpoints to be used during provisioning";
      default = [ ];
    };
    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";
    };
    postEndpoints = lib.mkOption {
      type = lib.types.listOf (
        lib.types.enum [
          "openstack"
          "aws"
          "unifi"
          "hcloud"
          "cloudflare"
          "vault"
        ]
      );
      description = "Needed endpoints to be used during provisioning";
      default = [ ];
    };
  };

  config = {
    khscodes.infrastructure.provisioning.preConfig = preConfig;
    khscodes.infrastructure.provisioning.preEndpoints = preEndpoints;
    khscodes.infrastructure.provisioning.postConfig = postConfig;
    khscodes.infrastructure.provisioning.postEndpoints = postEndpoints;
  };
}
