const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
const require_types_plugin = require('../types/plugin.cjs');
let powerlines_types_babel = require("powerlines/types/babel");
let __babel_core = require("@babel/core");
let __powerlines_deepkit_utilities = require("@powerlines/deepkit/utilities");
let __powerlines_plugin_babel_helpers_create_plugin = require("@powerlines/plugin-babel/helpers/create-plugin");
let __powerlines_plugin_babel_helpers_module_helpers = require("@powerlines/plugin-babel/helpers/module-helpers");
let __storm_software_config_tools_types = require("@storm-software/config-tools/types");

//#region src/babel/plugin.ts
function __assignType(fn, args) {
	fn.__type = args;
	return fn;
}
const envBabelPlugin = (__powerlines_plugin_babel_helpers_create_plugin.createBabelPlugin.Ω = [[() => require_types_plugin.__ΩEnvPluginContext, "n!"]], (0, __powerlines_plugin_babel_helpers_create_plugin.createBabelPlugin)("env", __assignType(({ log, context }) => {
	function extractEnv(node, pass, isInjectable = false) {
		const envTypesAliasProperties = context.env.types.env?.getProperties().filter(__assignType((prop) => prop.getAlias().length > 0, [
			"prop",
			"",
			"P\"2!\"/\""
		]));
		if (node.name) {
			const prefix = context.config.env.prefix.find(__assignType((pre) => node.name && node.name.startsWith(pre) && (context.env.types.env?.hasProperty(node.name.replace(`${pre}_`, "")) || envTypesAliasProperties.some(__assignType((prop) => prop.getAlias().includes(node.name.replace(`${pre}_`, "")), [
				"prop",
				"",
				"P\"2!\"/\""
			]))), [
				"pre",
				"",
				"P\"2!\"/\""
			]));
			let name = node.name;
			if (prefix) name = node.name.replace(`${prefix}_`, "");
			log(__storm_software_config_tools_types.LogLevelLabel.TRACE, `Environment variable ${name} found in ${pass.filename || "unknown file"}.`);
			if (context.env.types.env?.hasProperty(name) || envTypesAliasProperties.some(__assignType((prop) => prop.getAlias().includes(name), [
				"prop",
				"",
				"P\"2!\"/\""
			]))) {
				const envProperty = context.env.types.env.hasProperty(name) ? context.env.types.env.getProperty(name) : envTypesAliasProperties.find(__assignType((prop) => prop.getAlias().includes(name), [
					"prop",
					"",
					"P\"2!\"/\""
				]));
				if (!envProperty || envProperty.isIgnored()) return;
				if (!context.env.used.env.hasProperty(name)) {
					log(__storm_software_config_tools_types.LogLevelLabel.DEBUG, `Adding "${name}" environment variables found in "${pass.filename || "unknown file"}" to used environment configuration reflection object.`);
					context.env.used.env.addProperty(envProperty.property);
				}
				if (context.config.env.inject && isInjectable) {
					let value = context.env.parsed?.[name];
					if (value === void 0) {
						const prefix$1 = context.config.env.prefix.find(__assignType((pre) => {
							return context.env.parsed[`${pre.replace(/_$/g, "")}_${name}`];
						}, [
							"pre",
							"",
							"P\"2!\"/\""
						]));
						if (prefix$1) value = context.env.parsed[`${prefix$1.replace(/_$/g, "")}_${name}`];
					}
					value ??= envProperty.getDefaultValue();
					if (envProperty.isValueRequired() && value === void 0) throw new Error(`Environment variable \`${name}\` is not defined in the .env configuration files`);
					return (0, __powerlines_deepkit_utilities.stringifyDefaultValue)(envProperty, value);
				}
			} else throw new Error(`The "${name}" environment variable is not defined in the \`env\` type definition, but is used in the source code file ${pass.filename ? pass.filename : "unknown"}.

          The following environment configuration names are defined in the \`env\` type definition: \n${context.env.types.env?.getPropertyNames().sort(__assignType((a, b) => String(a).localeCompare(String(b)), [
				"a",
				"b",
				"",
				"P\"2!\"2\"\"/#"
			])).map(__assignType((typeDef) => ` - ${String(typeDef)} ${envTypesAliasProperties.some(__assignType((prop) => prop.getNameAsString() === String(typeDef) && prop.getAlias().length > 0, [
				"prop",
				"",
				"P\"2!\"/\""
			])) ? `(Alias: ${envTypesAliasProperties?.find(__assignType((prop) => prop.getNameAsString() === String(typeDef), [
				"prop",
				"",
				"P\"2!\"/\""
			]))?.getAlias().join(", ")})` : ""}`, [
				"typeDef",
				"",
				"P\"2!\"/\""
			])).join("\n")} \n\nUsing the following env prefix: \n${context.config.env.prefix.map(__assignType((prefix$1) => ` - ${prefix$1}`, [
				"prefix",
				"",
				"P\"2!\"/\""
			])).join("\n")} \n\nPlease check your \`env\` configuration option. If you are using a custom dotenv type definition, please make sure that the configuration names match the ones in the code. \n\n`);
		}
	}
	extractEnv.__type = [
		"node",
		() => powerlines_types_babel.__ΩBabelPluginPass,
		"pass",
		"isInjectable",
		"extractEnv",
		"P!2!n\"2#\"2$\"/%"
	];
	return { visitor: { MemberExpression: __assignType(function MemberExpression(path, pass) {
		if (path.get("object")?.get("property")?.isIdentifier({ name: "env" }) && path.get("object")?.get("object")?.isIdentifier({ name: "process" }) && path.get("property")?.isIdentifier()) {
			const identifier = path.get("property")?.node;
			if (!identifier.name) return;
			extractEnv(identifier, pass, false);
			path.replaceWithSourceString(`env.${identifier.name}`);
			(0, __powerlines_plugin_babel_helpers_module_helpers.addImport)(path, {
				module: `${context.config.framework || "powerlines"}:env`,
				name: "env",
				imported: "env"
			});
		} else if (path.get("object")?.get("property")?.isIdentifier({ name: "env" }) && path.get("object")?.get("object")?.isMetaProperty() && path.get("property")?.isIdentifier()) {
			const identifier = path.get("property")?.node;
			if (!identifier.name) return;
			extractEnv(identifier, pass, false);
			path.replaceWithSourceString(`env.${identifier.name}`);
			(0, __powerlines_plugin_babel_helpers_module_helpers.addImport)(path, {
				module: `${context.config.framework || "powerlines"}:env`,
				name: "env",
				imported: "env"
			});
		} else if (path.get("object")?.isIdentifier({ name: "env" }) && path.get("property")?.isIdentifier()) {
			const identifier = path.get("property")?.node;
			if (!identifier.name) return;
			extractEnv(identifier, pass, false);
		}
	}, [
		() => __babel_core.NodePath,
		"path",
		() => powerlines_types_babel.__ΩBabelPluginPass,
		"pass",
		"MemberExpression",
		"PP!7!2\"n#2$\"/%"
	]) } };
}, [
	"param0",
	"",
	"P\"2!\"/\""
])));

//#endregion
exports.envBabelPlugin = envBabelPlugin;