import { createLogger } from "../../utils/logger/index.js";
import { init_logger } from "../../utils/logger.js";
import { normalizeReasoningLevel, normalizeThinkLevel } from "../transcript/thinking-types.js";
import { normalizeWorkingDirectoryInput } from "../../session/session-workspace.js";
import "../../session/index.js";
import { mkdir } from "node:fs/promises";
//#region src/agent/session/session-config-service.ts
/**
* SessionConfigService — owns the "write side" of per-session agent settings
* (model override, thinking level, reasoning level, working directory).
*
* Previously these lived as four sibling methods on `AgentService`:
*   - `patchSessionAgentConfig` (96 lines of validation + persistence)
*   - `applyCronJobWorkingDirectory` (cron-specific working dir update)
*   - `clearCronSessionWorkingDirectoryOverride` (private helper)
*   - `clearSessionModelOverride` (private helper)
*
* Extracted so `AgentService` no longer mixes "session bag" concerns with
* "session config write" concerns, and so future additions to the patch API
* (e.g. new per-session overrides) only touch this file.
*/
init_logger();
const log = createLogger("SessionConfigService");
var SessionConfigService = class {
	opts;
	constructor(opts) {
		this.opts = opts;
	}
	/**
	* Apply a partial patch (model / thinking / reasoning / working directory) to
	* a session's persisted config. Returns `{ ok: false, error }` on the first
	* invalid field — earlier fields that succeeded are NOT rolled back, matching
	* the previous behaviour.
	*/
	async patch(sessionKey, partial) {
		if (partial.model !== void 0) if (partial.model === null || partial.model === "") await this.clearModelOverride(sessionKey);
		else {
			if (!await this.opts.modelManager.switchModelForSession(sessionKey, partial.model)) return {
				ok: false,
				error: "Invalid model"
			};
			await this.opts.sessionConfigStore.update(sessionKey, { modelOverride: partial.model });
			this.opts.agentManager.setModelForSession(sessionKey, partial.model);
		}
		if (partial.thinkingLevel !== void 0) {
			const normalized = normalizeThinkLevel(partial.thinkingLevel);
			if (!normalized) return {
				ok: false,
				error: "Invalid thinking level"
			};
			await this.opts.sessionConfigStore.update(sessionKey, { thinkingLevel: normalized });
			this.opts.agentManager.setThinkingLevel(sessionKey, normalized);
		}
		if (partial.reasoningLevel !== void 0) {
			const normalized = normalizeReasoningLevel(partial.reasoningLevel);
			if (!normalized) return {
				ok: false,
				error: "Invalid reasoning level"
			};
			await this.opts.sessionConfigStore.update(sessionKey, { reasoningLevel: normalized });
		}
		if (partial.workingDirectory !== void 0) {
			if (!this.opts.getConfig()) return {
				ok: false,
				error: "Config not loaded"
			};
			const result = await this.patchWorkingDirectory(sessionKey, partial.workingDirectory);
			if (!result.ok) return result;
		}
		return { ok: true };
	}
	/**
	* Sync persisted session working directory for an isolated cron run. Runs
	* may change when the job is edited; an empty/missing input clears the
	* override so the session uses the effective agent default.
	*/
	async applyCronJobWorkingDirectory(sessionKey, workingDirectory) {
		const raw = workingDirectory?.trim();
		if (raw) {
			const wdNorm = normalizeWorkingDirectoryInput(raw);
			if (wdNorm.ok === false) {
				log.warn({
					sessionKey,
					error: wdNorm.error
				}, "Cron job working directory invalid; using agent default");
				await this.clearCronWorkingDirectoryOverride(sessionKey);
				return;
			}
			await mkdir(wdNorm.path, { recursive: true });
			await this.opts.sessionConfigStore.update(sessionKey, { workingDirectoryOverride: wdNorm.path });
			this.opts.agentManager.setSessionWorkspaceOverride(sessionKey, wdNorm.path);
			return;
		}
		await this.clearCronWorkingDirectoryOverride(sessionKey);
	}
	/**
	* Clear the session's model override (back to agent default). Used both by
	* {@link patch} and by `AgentService.resetSessionModelToAgentDefault`.
	*/
	async clearModelOverride(sessionKey) {
		this.opts.modelManager.clearSessionModelOverride(sessionKey);
		await this.opts.sessionConfigStore.update(sessionKey, { modelOverride: void 0 });
		const agent = this.opts.agentManager.getAgent(sessionKey);
		if (agent) await this.opts.modelManager.applyModelForSession(agent, sessionKey);
	}
	async clearCronWorkingDirectoryOverride(sessionKey) {
		const existing = await this.opts.sessionConfigStore.get(sessionKey);
		if (existing?.workingDirectoryOverride) {
			const { workingDirectoryOverride: _removed, ...rest } = existing;
			await this.opts.sessionConfigStore.set(sessionKey, rest);
		}
		this.opts.agentManager.setSessionWorkspaceOverride(sessionKey, null);
	}
	/**
	* Apply the workingDirectory branch of `patch`. Returns the next-step result
	* (`ok: true` to keep going, `ok: false, error` to short-circuit the patch).
	*
	* Working directory has the strictest semantics: once a session has any
	* messages, it cannot move to a different directory — only re-setting the
	* same path is idempotent.
	*/
	async patchWorkingDirectory(sessionKey, workingDirectory) {
		const existingRaw = (await this.opts.sessionConfigStore.get(sessionKey))?.workingDirectoryOverride?.trim();
		const incoming = workingDirectory.trim();
		if ((await this.opts.sessionStore.load(sessionKey)).length > 0) {
			if (!incoming) return {
				ok: false,
				error: "workingDirectory is empty"
			};
			if (!existingRaw) return {
				ok: false,
				error: "Working directory can only be set before the first message in this conversation"
			};
			const prev = normalizeWorkingDirectoryInput(existingRaw);
			const next = normalizeWorkingDirectoryInput(incoming);
			if (prev.ok && next.ok && prev.path === next.path) return { ok: true };
			return {
				ok: false,
				error: "Working directory is already set for this session"
			};
		}
		if (!incoming) return {
			ok: false,
			error: "workingDirectory is empty"
		};
		const wdNorm = normalizeWorkingDirectoryInput(incoming);
		switch (wdNorm.ok) {
			case true:
				if (existingRaw) {
					const prev = normalizeWorkingDirectoryInput(existingRaw);
					if (prev.ok && prev.path === wdNorm.path) return { ok: true };
				}
				await mkdir(wdNorm.path, { recursive: true });
				await this.opts.sessionConfigStore.update(sessionKey, { workingDirectoryOverride: wdNorm.path });
				this.opts.agentManager.setSessionWorkspaceOverride(sessionKey, wdNorm.path);
				this.opts.agentManager.removeAgent(sessionKey);
				return { ok: true };
			case false: return {
				ok: false,
				error: wdNorm.error
			};
			default: return {
				ok: false,
				error: "Invalid working directory"
			};
		}
	}
};
//#endregion
export { SessionConfigService };

//# sourceMappingURL=session-config-service.js.map