import { t as debug_default } from "./debug-Dtkb5y8O.js";
import string from "@adonisjs/core/helpers/string";
import { MessageBuilder } from "@adonisjs/core/helpers";
import { dirname, join } from "node:path";
import { access, mkdir, readFile, rm, stat, utimes, writeFile } from "node:fs/promises";
//#region src/stores/file.ts
/**
* File store writes the session data on the file system. Each session
* id gets its own file for storage.
*
* @example
* const fileStore = new FileStore({
*   location: './tmp/sessions'
* }, '2 hours')
*/
var FileStore = class {
	/**
	* File store configuration
	*/
	#config;
	/**
	* Session age/expiry time
	*/
	#age;
	/**
	* Creates a new file store instance
	*
	* @param config - File store configuration
	* @param age - Session age in seconds or time expression (e.g. '2 hours')
	*/
	constructor(config, age) {
		this.#config = config;
		this.#age = age;
		debug_default("initiating file store %O", this.#config);
	}
	/**
	* Returns the absolute file path for a session ID.
	* Session files are stored with .txt extension in the configured location.
	*
	* @param sessionId - Session identifier
	*/
	#getFilePath(sessionId) {
		return join(this.#config.location, `${sessionId}.txt`);
	}
	/**
	* Checks if a file or directory exists at the given path.
	* Returns true if accessible, false otherwise.
	*
	* @param path - File or directory path to check
	*/
	async #pathExists(path) {
		try {
			await access(path);
			return true;
		} catch {
			return false;
		}
	}
	/**
	* Returns file statistics for the given path.
	* Returns null if the file doesn't exist or is inaccessible.
	*
	* @param path - File path to get stats for
	*/
	async #stats(path) {
		try {
			return await stat(path);
		} catch {
			return null;
		}
	}
	/**
	* Writes file contents to the given path.
	* Creates parent directories recursively if they don't exist.
	*
	* @param path - File path to write to
	* @param contents - File contents to write
	*/
	async #outputFile(path, contents) {
		const pathDirname = dirname(path);
		if (!await this.#pathExists(pathDirname)) await mkdir(pathDirname, { recursive: true });
		await writeFile(path, contents, "utf-8");
	}
	/**
	* Reads the session data from the disk
	*
	* @param sessionId - Session identifier
	*
	* @example
	* const data = await store.read('sess_abc123')
	*/
	async read(sessionId) {
		const filePath = this.#getFilePath(sessionId);
		debug_default("file store: reading session data %", sessionId);
		/**
		* Return null when no session id file exists in first
		* place
		*/
		const stats = await this.#stats(filePath);
		if (!stats) return null;
		/**
		* Check if the file has been expired and return null (if expired)
		*/
		const sessionWillExpireAt = stats.mtimeMs + string.seconds.parse(this.#age) * 1e3;
		if (Date.now() > sessionWillExpireAt) {
			debug_default("file store: expired session data %s", sessionId);
			return null;
		}
		/**
		* Reading the file contents if the file exists
		*/
		let contents = await readFile(filePath, "utf-8");
		contents = contents.trim();
		if (!contents) return null;
		/**
		* Verify contents with the session id and return them as an object. The verify
		* method can fail when the contents is not JSON>
		*/
		try {
			return new MessageBuilder().verify(contents, sessionId);
		} catch {
			return null;
		}
	}
	/**
	* Writes the session data to the disk as a string
	*
	* @param sessionId - Session identifier
	* @param values - Session data to store
	*
	* @example
	* await store.write('sess_abc123', { userId: 123 })
	*/
	async write(sessionId, values) {
		debug_default("file store: writing session data %s: %O", sessionId, values);
		const filePath = this.#getFilePath(sessionId);
		const message = new MessageBuilder().build(values, void 0, sessionId);
		await this.#outputFile(filePath, message);
	}
	/**
	* Removes the session file from the disk
	*
	* @param sessionId - Session identifier
	*
	* @example
	* await store.destroy('sess_abc123')
	*/
	async destroy(sessionId) {
		debug_default("file store: destroying session data %s", sessionId);
		await rm(this.#getFilePath(sessionId), { force: true });
	}
	/**
	* Updates the session expiry by updating the file's modification time
	*
	* @param sessionId - Session identifier
	*
	* @example
	* await store.touch('sess_abc123')
	*/
	async touch(sessionId) {
		debug_default("file store: touching session data %s", sessionId);
		await utimes(this.#getFilePath(sessionId), /* @__PURE__ */ new Date(), /* @__PURE__ */ new Date());
	}
};
//#endregion
export { FileStore };
