import { a as isPathInside } from "./path-D138yf8v.js";
import "./path-guards-CQoZeoCG.js";
import { t as hasErrnoCode } from "./errno-CkbDOfLk.js";
import { w as resolveStateDir } from "./paths-BBSTUjD5.js";
import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js";
import { s as isSessionArchiveArtifactName } from "./artifacts-FzMa6c2e.js";
import { F as createOpenClawAgentDatabasePathMatcher, I as isPersistentOpenClawAgentDatabasePath, V as listOpenClawRegisteredAgentDatabases, z as unregisterOpenClawAgentDatabase } from "./openclaw-agent-db-maintenance-C4D8xHaF.js";
import { n as resolveAgentSessionDirsFromAgentsDirSync } from "./session-dirs-SATsXf4g.js";
import fs from "node:fs";
import path from "node:path";
//#region src/infra/state-migrations.media-persistence-targets.ts
function listDefaultAgentDatabaseTargets(env, failure) {
	const agentsDir = path.join(resolveStateDir(env), "agents");
	try {
		return resolveAgentSessionDirsFromAgentsDirSync(agentsDir).map((sessionsDir) => {
			const agentDir = path.dirname(sessionsDir);
			return {
				agentId: normalizeAgentId(path.basename(agentDir)),
				path: path.join(agentDir, "agent", "openclaw-agent.sqlite"),
				source: "disk"
			};
		});
	} catch (error) {
		failure(agentsDir, `Could not enumerate agent databases under ${agentsDir}: ${String(error)}`);
		return [];
	}
}
/** Discover maintenance targets without mutating the registry or creating stores. */
function discoverAgentDatabaseMigrationTargets(params) {
	const warnings = [];
	const failures = [];
	const registryRemovals = [];
	const failure = (pathname, reason) => {
		warnings.push(reason);
		failures.push({
			path: pathname,
			reason
		});
	};
	const discard = (candidate, change) => {
		if (candidate.source === "registry") registryRemovals.push({
			agentId: candidate.agentId,
			path: candidate.path,
			change
		});
	};
	const candidates = [
		...params.configuredAgentDatabaseTargets.map((target) => ({
			agentId: target.agentId,
			path: target.path,
			source: "configured"
		})),
		...params.registeredAgentDatabases.map((entry) => ({
			agentId: entry.agentId,
			path: entry.path,
			source: "registry"
		})),
		...listDefaultAgentDatabaseTargets(params.env, failure)
	];
	const activeStateDir = resolveStateDir(params.env);
	let activeStateDirRealPath;
	try {
		activeStateDirRealPath = fs.realpathSync.native(activeStateDir);
	} catch (error) {
		if (!hasErrnoCode(error, "ENOENT")) failure(activeStateDir, `Could not resolve active state directory ${activeStateDir}: ${String(error)}`);
	}
	const configuredPathMatcher = createOpenClawAgentDatabasePathMatcher();
	const targets = [];
	const seenRealPaths = /* @__PURE__ */ new Set();
	for (const candidate of candidates) {
		const pathname = candidate.path;
		if (!isPersistentOpenClawAgentDatabasePath(pathname, params.env)) {
			discard(candidate, `Removed archived or transient agent database registry entry ${pathname}.`);
			continue;
		}
		let realPath;
		try {
			realPath = fs.realpathSync.native(pathname);
		} catch (error) {
			if (!hasErrnoCode(error, "ENOENT")) failure(pathname, `Could not resolve agent database ${pathname}: ${String(error)}`);
		}
		const isConfiguredPath = realPath !== void 0 && params.configuredAgentDatabaseTargets.some((configuredTarget) => {
			if (normalizeAgentId(configuredTarget.agentId) !== normalizeAgentId(candidate.agentId)) return false;
			try {
				return configuredPathMatcher(pathname, configuredTarget.path);
			} catch {
				return false;
			}
		});
		const isInsideActiveStateDir = Boolean(realPath && activeStateDirRealPath && (realPath === activeStateDirRealPath || isPathInside(activeStateDirRealPath, realPath)));
		if (realPath && !isInsideActiveStateDir && !isConfiguredPath) {
			discard(candidate);
			warnings.push(`Skipped foreign agent database ${pathname}; it is outside the active state directory and is not a configured session store.`);
			continue;
		}
		let stat;
		try {
			stat = fs.statSync(pathname);
		} catch (error) {
			if (!hasErrnoCode(error, "ENOENT")) {
				failure(pathname, `Could not inspect ${candidate.source === "registry" ? "registered " : ""}agent database ${pathname}: ${String(error)}`);
				continue;
			}
		}
		if (!stat?.isFile()) {
			discard(candidate, `Removed missing agent database registry entry ${pathname}.`);
			if (candidate.source === "registry") warnings.push(`Skipped missing registered agent database ${pathname}.`);
			continue;
		}
		if (!realPath) {
			discard(candidate);
			warnings.push(`Skipped agent database ${pathname}; its filesystem boundary is unresolved.`);
			continue;
		}
		if (seenRealPaths.has(realPath)) continue;
		seenRealPaths.add(realPath);
		targets.push({
			...candidate,
			path: pathname,
			realPath
		});
	}
	return {
		targets,
		registryRemovals,
		warnings,
		failures
	};
}
/** Migration alone owns cleanup of stale registry entries discovered above. */
function resolveAgentDatabaseMigrationTargets(params) {
	let registeredAgentDatabases = [];
	try {
		registeredAgentDatabases = listOpenClawRegisteredAgentDatabases({
			env: params.env,
			includeIncompatibleSchemaVersions: true
		});
	} catch (error) {
		params.warnings.push(`Failed enumerating registered agent databases for state migration: ${String(error)}`);
	}
	const discovery = discoverAgentDatabaseMigrationTargets({
		...params,
		registeredAgentDatabases
	});
	for (const removed of discovery.registryRemovals) {
		unregisterOpenClawAgentDatabase({
			...removed,
			env: params.env
		});
		if (removed.change) params.changes.push(removed.change);
	}
	params.warnings.push(...discovery.warnings);
	return discovery.targets;
}
function listTranscriptArchives(directory) {
	let entries;
	try {
		entries = fs.readdirSync(directory, { withFileTypes: true });
	} catch (error) {
		if (hasErrnoCode(error, "ENOENT")) return [];
		throw error;
	}
	return entries.filter((entry) => entry.isFile() && entry.name.includes(".jsonl.") && isSessionArchiveArtifactName(entry.name)).map((entry) => path.join(directory, entry.name));
}
//#endregion
export { listTranscriptArchives as n, resolveAgentDatabaseMigrationTargets as r, discoverAgentDatabaseMigrationTargets as t };
