import { __ΩEnvInterface, __ΩSecretsInterface } from "./types/runtime.mjs";
import { __ΩEnvPluginContext, __ΩEnvPluginOptions, __ΩEnvPluginResolvedConfig, __ΩEnvPluginUserConfig, __ΩEnvType } from "./types/plugin.mjs";
import "./types/index.mjs";
import { joinPaths } from "./node_modules/.pnpm/@stryke_path@0.26.4/node_modules/@stryke/path/dist/join-paths.mjs";
import { isParentPath } from "./node_modules/.pnpm/@stryke_path@0.26.4/node_modules/@stryke/path/dist/is-parent-path.mjs";
import { BaseEnv, BaseSecrets, __ΩCreateEnvReflectionOptions, createEnvReflection, createSecretsReflection, mergeEnvReflections, mergeSecretsReflections, reflectEnv, reflectSecrets } from "./helpers/reflect.mjs";
import { getEnvDefaultTypeDefinition, getEnvReflectionsPath, getEnvTypeReflectionsPath, getSecretsDefaultTypeDefinition, readEnvReflection, readEnvTypeReflection, readSecretsReflection, resolveRuntimeTypeFile, writeEnvReflection, writeEnvReflectionSync, writeEnvTypeReflection } from "./helpers/persistence.mjs";
import { createTemplateReflection } from "./helpers/template-helpers.mjs";
import { formatEnvField, removeEnvPrefix } from "./helpers/source-file-env.mjs";
import { defu } from "./node_modules/.pnpm/defu@6.1.4/node_modules/defu/dist/defu.mjs";
import { loadEnv, loadEnvFromContext } from "./helpers/load.mjs";
import { createReflection } from "./helpers/create-reflection-resource.mjs";
import "./helpers/index.mjs";
import { getDocsOutputPath } from "./helpers/docs-helper.mjs";
import { env } from "./helpers/automd-generator.mjs";
import { EnvDocsFile } from "./components/docs.mjs";
import { EnvBuiltin, EnvTypeDefinition } from "./components/env.mjs";
import "./components/index.mjs";
import { envBabelPlugin } from "./babel/plugin.mjs";
import "./babel/index.mjs";
import { parseTypeDefinition } from "./node_modules/.pnpm/@stryke_convert@0.6.38/node_modules/@stryke/convert/dist/parse-type-definition.mjs";
import { toArray } from "./node_modules/.pnpm/@stryke_convert@0.6.38/node_modules/@stryke/convert/dist/to-array.mjs";
import { ReflectionClass, ReflectionKind } from "@powerlines/deepkit/vendor/type";
import { ENV_PREFIXES } from "@stryke/env/types";
import { createComponent } from "@alloy-js/core/jsx-runtime";
import alloy from "@powerlines/plugin-alloy";
import { render } from "@powerlines/plugin-alloy/render";
import automd from "@powerlines/plugin-automd";
import babel from "@powerlines/plugin-babel";
import { existsSync } from "@stryke/fs/exists";
import { constantCase } from "@stryke/string-format/constant-case";

//#region src/index.tsx
/**
* A Powerlines plugin to inject environment variables into the source code.
*/
const plugin = (options = {}) => {
	return [
		alloy(options.alloy),
		babel(options.babel),
		{
			name: "env",
			async config() {
				this.debug("Providing default configuration for the Powerlines `env` build plugin.");
				const config = {
					env: defu(options, {
						types: {},
						prefix: []
					}),
					transform: { babel: { plugins: [envBabelPlugin] } }
				};
				if (config.env.types) config.env.types = parseTypeDefinition(config.env.types);
				else {
					this.warn("The `env.types` configuration parameter was not provided. Please ensure this is expected.");
					const envDefaultTypeDefinition = await getEnvDefaultTypeDefinition(this);
					config.env.types = parseTypeDefinition(`${envDefaultTypeDefinition.file}#${envDefaultTypeDefinition.name}`);
				}
				if (config.env.secrets) config.env.secrets = parseTypeDefinition(config.env.secrets);
				else {
					const secretsDefaultTypeDefinition = await getSecretsDefaultTypeDefinition(this);
					config.env.secrets = parseTypeDefinition(`${secretsDefaultTypeDefinition.file}#${secretsDefaultTypeDefinition.name}`);
				}
				config.env.prefix = toArray(config.env.prefix ?? []).reduce((ret, prefix) => {
					const formattedPrefix = constantCase(prefix);
					if (!ret.includes(formattedPrefix)) ret.push(formattedPrefix);
					return ret;
				}, [
					...ENV_PREFIXES,
					"POWERLINES_",
					this.config.framework && this.config.framework !== "powerlines" && `${constantCase(this.config.framework)}_`
				].filter(Boolean));
				config.env.prefix = toArray(config.env.prefix).reduce((ret, prefix) => {
					if (!ret.includes(prefix.replace(/_$/g, ""))) ret.push(prefix.replace(/_$/g, ""));
					return ret;
				}, []);
				return config;
			},
			async configResolved() {
				this.debug(`Environment plugin configuration has been resolved for the Powerlines project.`);
				this.env = defu({ parsed: await loadEnv(this, this.config.env) }, this.env ?? {}, {
					types: { env: {} },
					used: {
						env: {},
						secrets: {}
					},
					parsed: {},
					injected: {}
				});
				if (this.config.command !== "prepare" && !this.config.skipCache && this.persistedMeta?.checksum === this.meta.checksum && existsSync(getEnvTypeReflectionsPath(this, "env"))) {
					this.debug(`Skipping reflection initialization as the meta checksum has not changed.`);
					this.env.types.env = await readEnvTypeReflection(this, "env");
					if (existsSync(getEnvReflectionsPath(this, "env"))) this.env.used.env = await readEnvReflection(this);
					if (existsSync(getEnvTypeReflectionsPath(this, "secrets"))) this.env.types.secrets = await readEnvTypeReflection(this, "secrets");
					if (existsSync(getEnvReflectionsPath(this, "secrets"))) this.env.used.secrets = await readSecretsReflection(this);
				} else {
					this.debug(`Starting environment configuration reflection initialization.`);
					this.env.types.env = await reflectEnv(this, this.config.env.types?.file ? isParentPath(this.config.env.types?.file, this.workspaceConfig.workspaceRoot) ? this.config.env.types?.file : joinPaths(this.config.projectRoot, this.config.env.types?.file) : void 0, this.config.env.types?.name);
					if (!this.env.types.env) throw new Error("Failed to find the environment configuration type reflection in the context.");
					await writeEnvTypeReflection(this, this.env.types.env, "env");
					this.env.types.secrets = await reflectSecrets(this, this.config.env.secrets?.file ? isParentPath(this.config.env.secrets?.file, this.workspaceConfig.workspaceRoot) ? this.config.env.secrets?.file : joinPaths(this.config.projectRoot, this.config.env.secrets?.file) : void 0, this.config.env.secrets?.name);
					if (!this.env.types.secrets) throw new Error("Failed to find the secrets configuration type reflection in the context.");
					await writeEnvTypeReflection(this, this.env.types.secrets, "secrets");
					this.debug(`Resolved ${this.env.types.env.getProperties().length ?? 0} environment configuration parameters and ${this.env.types.secrets?.getProperties().length ?? 0} secret configuration parameters`);
					const envWithAlias = this.env.types.env.getProperties().filter((prop) => prop.getAlias().length > 0);
					Object.entries(await loadEnv(this, this.config.env)).forEach(([key, value]) => {
						const unprefixedKey = this.config.env.prefix.reduce((ret, prefix) => {
							if (key.replace(/_$/g, "").startsWith(prefix)) return key.replace(/_$/g, "").slice(prefix.length);
							return ret;
						}, key);
						const aliasKey = envWithAlias.find((prop) => prop?.getAlias().reverse().includes(unprefixedKey));
						if (this.env.types.env?.hasProperty(unprefixedKey) || aliasKey) this.env.types.env.getProperty(unprefixedKey).setDefaultValue(value);
					});
					this.env.used.env = new ReflectionClass({
						kind: ReflectionKind.objectLiteral,
						typeName: "Env",
						description: `An object containing the environment configuration parameters used by the ${this.config.name ? `${this.config.name} application` : "application"}.`,
						types: []
					}, this.env.types.env);
					await writeEnvReflection(this, this.env.used.env, "env");
					if (this.env.types.secrets) {
						await writeEnvTypeReflection(this, this.env.types.secrets, "secrets");
						this.env.used.secrets = new ReflectionClass({
							kind: ReflectionKind.objectLiteral,
							typeName: "Secrets",
							description: `An object containing the secret configuration parameters used by the ${this.config.name ? `${this.config.name} application` : "application"}.`,
							types: []
						}, this.env.types.secrets);
						await writeEnvReflection(this, this.env.used.secrets, "secrets");
					}
				}
			},
			async prepare() {
				const _self$ = this;
				this.debug(`Preparing the Environment runtime artifacts for the Powerlines project.`);
				const result = await readEnvTypeReflection(this, "env");
				return render(this, createComponent(EnvBuiltin, {
					get defaultConfig() {
						return _self$.config.env.defaultConfig;
					},
					reflection: result
				}));
			},
			transform: {
				order: "post",
				async handler() {
					if (this.env.used.env.getProperties().length > 0) {
						this.trace(`Persisting used environment configuration reflections to ${getEnvReflectionsPath(this, "env")}.`);
						await writeEnvReflection(this, this.env.used.env, "env");
					}
					if (this.env.used.secrets.getProperties().length > 0) {
						this.trace(`Persisting used secret configuration reflections to ${getEnvReflectionsPath(this, "secrets")}.`);
						await writeEnvReflection(this, this.env.used.secrets, "secrets");
					}
				}
			},
			async docs() {
				this.debug(`Documenting environment variables configuration values in "${joinPaths(getDocsOutputPath(this), "env.md")}"`);
				const result = await readEnvTypeReflection(this, "env");
				return render(this, createComponent(EnvDocsFile, {
					levelOffset: 0,
					reflection: result
				}));
			},
			async buildEnd() {
				const reflectionPath = getEnvReflectionsPath(this, "env");
				this.debug(`Writing env reflection types to ${reflectionPath}.`);
				await writeEnvReflection(this, this.env.used.env, "env");
			}
		},
		{
			name: "env:automd-generator",
			config() {
				return { automd: defu(options.automd ?? {}, { generators: { env: env(this) } }) };
			}
		},
		{
			name: "env:vite",
			vite: { configResolved() {
				return { envPrefix: this.config?.env?.prefix };
			} }
		},
		automd(options.automd)
	];
};
var src_default = plugin;

//#endregion
export { BaseEnv, BaseSecrets, EnvBuiltin, EnvDocsFile, EnvTypeDefinition, __ΩCreateEnvReflectionOptions, __ΩEnvInterface, __ΩEnvPluginContext, __ΩEnvPluginOptions, __ΩEnvPluginResolvedConfig, __ΩEnvPluginUserConfig, __ΩEnvType, __ΩSecretsInterface, createEnvReflection, createReflection, createSecretsReflection, createTemplateReflection, src_default as default, envBabelPlugin, formatEnvField, getEnvDefaultTypeDefinition, getEnvReflectionsPath, getEnvTypeReflectionsPath, getSecretsDefaultTypeDefinition, loadEnv, loadEnvFromContext, mergeEnvReflections, mergeSecretsReflections, plugin, readEnvReflection, readEnvTypeReflection, readSecretsReflection, reflectEnv, reflectSecrets, removeEnvPrefix, resolveRuntimeTypeFile, writeEnvReflection, writeEnvReflectionSync, writeEnvTypeReflection };
//# sourceMappingURL=index.mjs.map