import { __ΩEnvPluginContext, __ΩEnvPluginResolvedConfig, __ΩEnvType } from "../types/plugin.mjs";
import { joinPaths } from "../node_modules/.pnpm/@stryke_path@0.26.4/node_modules/@stryke/path/dist/join-paths.mjs";
import { createEnvReflection } from "./reflect.mjs";
import { ReflectionClass, ReflectionKind, deserializeType, resolveClassType } from "@powerlines/deepkit/vendor/type";
import { __ΩContext, __ΩUnresolvedContext } from "powerlines/types/context";
import { convertFromCapnp, convertToCapnp } from "@powerlines/deepkit/capnp";
import { getReflectionsPath } from "@powerlines/deepkit/resolve-reflections";
import { SerializedTypes } from "@powerlines/deepkit/schemas/reflection";
import * as capnp from "@stryke/capnp";
import { readFileBuffer, writeFileBuffer, writeFileBufferSync } from "@stryke/fs/buffer";
import { isEmptyObject } from "@stryke/type-checks/is-empty-object";
import { existsSync } from "node:fs";

//#region src/helpers/persistence.ts
/**
* Resolves the runtime type definition file for the environment variables.
*
* @param context - The plugin context.
* @returns The runtime type definition file for the environment variables.
*/
async function resolveRuntimeTypeFile(context) {
	const resolved = await context.fs.resolve("@powerlines/plugin-env/types/runtime");
	if (!resolved) throw new Error(`Failed to resolve the runtime type definition file for the environment variables. Please ensure that the "@powerlines/plugin-env" package is installed.`);
	return resolved;
}
resolveRuntimeTypeFile.__type = [
	() => __ΩUnresolvedContext,
	() => __ΩEnvPluginResolvedConfig,
	"context",
	"resolveRuntimeTypeFile",
	"Resolves the runtime type definition file for the environment variables.",
	"Pn\"o!\"2#&`/$?%"
];
/**
* Gets the default type definition for the environment variables.
*
* @param context - The plugin context.
* @returns The default type definition for the environment variables.
*/
async function getEnvDefaultTypeDefinition(context) {
	return {
		file: await resolveRuntimeTypeFile(context),
		name: "EnvInterface"
	};
}
getEnvDefaultTypeDefinition.__type = [
	() => __ΩUnresolvedContext,
	() => __ΩEnvPluginResolvedConfig,
	"context",
	"getEnvDefaultTypeDefinition",
	"Gets the default type definition for the environment variables.",
	"Pn\"o!\"2#!`/$?%"
];
/** Gets the default type definition for the environment secrets.
*
* @param context - The plugin context.
* @returns The default type definition for the environment secrets.
*/
async function getSecretsDefaultTypeDefinition(context) {
	return {
		file: await resolveRuntimeTypeFile(context),
		name: "SecretsInterface"
	};
}
getSecretsDefaultTypeDefinition.__type = [
	() => __ΩUnresolvedContext,
	() => __ΩEnvPluginResolvedConfig,
	"context",
	"getSecretsDefaultTypeDefinition",
	"Pn\"o!\"2#!`/$"
];
/**
* Gets the path to the environment type reflections.
*
* @param context - The plugin context.
* @param name - The name of the type reflections.
* @returns The path to the environment type reflections.
*/
function getEnvTypeReflectionsPath(context, name = "env") {
	return joinPaths(getReflectionsPath(context), "env", `${name}-types.bin`);
}
getEnvTypeReflectionsPath.__type = [
	() => __ΩContext,
	() => __ΩEnvPluginResolvedConfig,
	"context",
	() => __ΩEnvType,
	"name",
	() => "env",
	"getEnvTypeReflectionsPath",
	"Gets the path to the environment type reflections.",
	"Pn\"o!\"2#n$2%>&&/'?("
];
/**
* Reads the environment type reflection from the file system.
*
* @param context - The plugin context.
* @param name - The name of the type reflections.
* @returns The environment type reflection.
*/
async function readEnvTypeReflection(context, name = "env") {
	const filePath = getEnvTypeReflectionsPath(context, name);
	if (!existsSync(filePath)) {
		if (!context.env.types.env || isEmptyObject(context.env.types.env)) {
			const reflection$1 = createEnvReflection(context);
			const message = new capnp.Message();
			reflection$1.messageRoot = message.initRoot(SerializedTypes);
			reflection$1.dataBuffer = message.toArrayBuffer();
			context.env.types.env = reflection$1;
			await writeEnvTypeReflection(context, context.env.types.env, name);
		}
		return context.env.types.env;
	}
	const buffer = await readFileBuffer(filePath);
	const messageRoot = new capnp.Message(buffer, false).getRoot(SerializedTypes);
	const reflection = resolveClassType(deserializeType(convertFromCapnp(messageRoot.types)));
	context.env.types[name] = reflection;
	context.env.types[name].messageRoot = messageRoot;
	context.env.types[name].dataBuffer = buffer;
	return reflection;
}
readEnvTypeReflection.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => __ΩEnvType,
	"name",
	() => "env",
	() => ReflectionClass,
	"readEnvTypeReflection",
	"Reads the environment type reflection from the file system.",
	"Pn!2\"n#2$>%P\"7&`/'?("
];
/**
* Writes the environment type reflection to the file system.
*
* @param context - The plugin context.
* @param reflection - The environment type reflection to write.
* @param name - The name of the type reflections.
*/
async function writeEnvTypeReflection(context, reflection, name = "env") {
	const serialized = reflection.serializeType();
	const message = new capnp.Message();
	convertToCapnp(serialized, message.initRoot(SerializedTypes)._initTypes(serialized.length));
	await writeFileBuffer(getEnvTypeReflectionsPath(context, name), message.toArrayBuffer());
}
writeEnvTypeReflection.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => ReflectionClass,
	"reflection",
	() => __ΩEnvType,
	"name",
	() => "env",
	"writeEnvTypeReflection",
	"Writes the environment type reflection to the file system.",
	"Pn!2\"P\"7#2$n%2&>'\"/(?)"
];
function getEnvReflectionsPath(context, name) {
	return joinPaths(getReflectionsPath(context), "env", `${name}.bin`);
}
getEnvReflectionsPath.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => __ΩEnvType,
	"name",
	"getEnvReflectionsPath",
	"Pn!2\"n#2$&/%"
];
/**
* Reads the environment reflection data from the file system.
*
* @param context - The plugin context.
* @returns The environment reflection data.
*/
async function readEnvReflection(context) {
	const filePath = getEnvReflectionsPath(context, "env");
	if (!existsSync(filePath)) {
		if (!context.env.types.env) context.env.types.env = await readEnvTypeReflection(context, "env");
		if (!context.env.used.env || isEmptyObject(context.env.used.env)) {
			const reflection$1 = createEnvReflection(context, {
				type: {
					kind: ReflectionKind.objectLiteral,
					typeName: "Env",
					description: `An object containing the environment configuration parameters that are used (at least once) by the ${context.config.name ? `${context.config.name} application` : "application"}.`,
					types: []
				},
				superReflection: context.env.types.env
			});
			reflection$1.name = "Env";
			const message = new capnp.Message();
			reflection$1.messageRoot = message.initRoot(SerializedTypes);
			reflection$1.dataBuffer = message.toArrayBuffer();
			context.env.used.env = reflection$1;
			await writeEnvReflection(context, context.env.used.env, "env");
		}
		return context.env.used.env;
	}
	const buffer = await readFileBuffer(filePath);
	const messageRoot = new capnp.Message(buffer, false).getRoot(SerializedTypes);
	const reflection = resolveClassType(deserializeType(convertFromCapnp(messageRoot.types)));
	context.env.used.env = reflection;
	context.env.used.env.messageRoot = messageRoot;
	context.env.used.env.dataBuffer = buffer;
	return reflection;
}
readEnvReflection.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => ReflectionClass,
	"readEnvReflection",
	"Reads the environment reflection data from the file system.",
	"Pn!2\"P\"7#`/$?%"
];
/**
* Reads the secret environment reflection data from the file system.
*
* @param context - The plugin context.
* @returns The environment reflection data.
*/
async function readSecretsReflection(context) {
	const filePath = getEnvReflectionsPath(context, "secrets");
	if (!existsSync(filePath)) {
		if (!context.env.types.secrets) context.env.types.secrets = await readEnvTypeReflection(context, "secrets");
		if (!context.env.used.secrets || isEmptyObject(context.env.used.secrets)) {
			const reflection$1 = createEnvReflection(context, {
				type: {
					kind: ReflectionKind.objectLiteral,
					typeName: "Secrets",
					description: `An object containing the secret configuration parameters that are used (at least once) by the ${context.config.name ? `${context.config.name} application` : "application"}.`,
					types: []
				},
				superReflection: context.env.types.secrets
			});
			reflection$1.name = "Secrets";
			const message = new capnp.Message();
			reflection$1.messageRoot = message.initRoot(SerializedTypes);
			reflection$1.dataBuffer = message.toArrayBuffer();
			context.env.used.secrets = reflection$1;
			await writeEnvReflection(context, context.env.used.secrets, "secrets");
		}
		return context.env.used.secrets;
	}
	const buffer = await readFileBuffer(filePath);
	const messageRoot = new capnp.Message(buffer, false).getRoot(SerializedTypes);
	const reflection = resolveClassType(deserializeType(convertFromCapnp(messageRoot.types)));
	context.env.used.secrets = reflection;
	context.env.used.secrets.messageRoot = messageRoot;
	context.env.used.secrets.dataBuffer = buffer;
	return reflection;
}
readSecretsReflection.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => ReflectionClass,
	"readSecretsReflection",
	"Reads the secret environment reflection data from the file system.",
	"Pn!2\"P\"7#`/$?%"
];
/**
* Writes the environment reflection data to the file system.
*
* @param context - The plugin context.
* @param reflection - The reflection data to write.
* @param name - The name of the reflection (either "env" or "secrets").
*/
async function writeEnvReflection(context, reflection, name = "env") {
	const serialized = reflection.serializeType();
	const message = new capnp.Message();
	convertToCapnp(serialized, message.initRoot(SerializedTypes)._initTypes(serialized.length));
	await writeFileBuffer(getEnvReflectionsPath(context, name), message.toArrayBuffer());
}
writeEnvReflection.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => ReflectionClass,
	"reflection",
	() => __ΩEnvType,
	"name",
	() => "env",
	"writeEnvReflection",
	"Writes the environment reflection data to the file system.",
	"Pn!2\"P\"7#2$n%2&>'\"/(?)"
];
/**
* Writes the environment reflection data to the file system.
*
* @param context - The plugin context.
* @param reflection - The reflection data to write.
* @param name - The name of the reflection (either "env" or "secrets").
*/
function writeEnvReflectionSync(context, reflection, name = "env") {
	const serialized = reflection.serializeType();
	const message = new capnp.Message();
	convertToCapnp(serialized, message.initRoot(SerializedTypes)._initTypes(serialized.length));
	writeFileBufferSync(getEnvReflectionsPath(context, name), message.toArrayBuffer());
}
writeEnvReflectionSync.__type = [
	() => __ΩEnvPluginContext,
	"context",
	() => ReflectionClass,
	"reflection",
	() => __ΩEnvType,
	"name",
	() => "env",
	"writeEnvReflectionSync",
	"Writes the environment reflection data to the file system.",
	"Pn!2\"P\"7#2$n%2&>'\"/(?)"
];

//#endregion
export { getEnvDefaultTypeDefinition, getEnvReflectionsPath, getEnvTypeReflectionsPath, getSecretsDefaultTypeDefinition, readEnvReflection, readEnvTypeReflection, readSecretsReflection, resolveRuntimeTypeFile, writeEnvReflection, writeEnvReflectionSync, writeEnvTypeReflection };
//# sourceMappingURL=persistence.mjs.map