//#region src/infrastructure/logging/ConsoleLogger.ts
var ConsoleLogger = class {
	constructor(scope, logLevelPolicy) {
		this.scope = scope;
		this.logLevelPolicy = logLevelPolicy;
	}
	info(message, exception) {
		this.log("info", message, exception);
	}
	warn(message, exception) {
		this.log("warn", message, exception);
	}
	error(message, exception) {
		this.log("error", message, exception);
	}
	debug(message, exception) {
		this.log("debug", message, exception);
	}
	formatTimestamp() {
		return (/* @__PURE__ */ new Date()).toISOString();
	}
	log(level, message, exception) {
		if (!this.logLevelPolicy.shouldEmit(level, this.scope)) return;
		const line = `[${level}][${this.scope}][${this.formatTimestamp()}]: ${message}`;
		if (exception) {
			console[level](line, exception);
			return;
		}
		console[level](line);
	}
};

//#endregion
//#region src/infrastructure/logging/LogLevelPolicy.ts
const levelRank = {
	debug: 0,
	info: 1,
	warn: 2,
	error: 3
};
const globRegexMetaChars = /* @__PURE__ */ new Set("\\^$+?()[]{}|.");
/**
* Minimum log level for @codemation/host loggers.
* - `CODEMATION_LOG_LEVEL` overrides when set to a known level (for namespaces not matched by `codemation.config` log rules).
* - Under Vitest, defaults to **warn** so routine `info`/`debug` noise stays off the terminal; `warn`/`error` still print.
* - Otherwise defaults to **info**.
*
* When {@link applyCodemationLogConfig} is set, the first matching rule wins per namespace; unmatched namespaces use env defaults.
*
* Resolve a shared instance via {@link LogLevelPolicyFactory} (DI or `logLevelPolicyFactory`).
*/
var LogLevelPolicy = class {
	cachedMin;
	codemationRules = null;
	resolveMin() {
		const raw = process.env.CODEMATION_LOG_LEVEL?.toLowerCase();
		if (raw === "silent" || raw === "debug" || raw === "info" || raw === "warn" || raw === "error") return raw;
		if (process.env.VITEST === "true") return "warn";
		return "info";
	}
	minLevelCached() {
		if (this.cachedMin === void 0) this.cachedMin = this.resolveMin();
		return this.cachedMin;
	}
	resetForTests() {
		this.cachedMin = void 0;
		this.codemationRules = null;
	}
	/**
	* Applies `codemation.config` log rules. Pass `undefined` to clear rules and use env-only behavior.
	*/
	applyCodemationLogConfig(config) {
		this.codemationRules = null;
		if (!config) return;
		const rawRules = this.normalizeCodemationRules(config);
		if (rawRules.length === 0) return;
		const compiled = [];
		for (const rule of rawRules) {
			const minLevel = this.parseRuleLevel(rule.level);
			const patterns = this.normalizeFilterPatterns(rule.filter);
			if (patterns.length === 0) throw new Error("codemation.config log rule filter must include at least one pattern");
			const matchers = patterns.map((pattern) => this.compileGlobPattern(pattern));
			compiled.push({
				matchers,
				minLevel
			});
		}
		this.codemationRules = compiled;
	}
	shouldEmit(level, namespace) {
		if (this.codemationRules && this.codemationRules.length > 0) {
			for (const rule of this.codemationRules) if (rule.matchers.some((regex) => regex.test(namespace))) return this.levelPassesAgainstMin(level, rule.minLevel);
		}
		return this.levelPassesAgainstMin(level, this.minLevelCached());
	}
	normalizeCodemationRules(config) {
		if ("rules" in config && Array.isArray(config.rules)) return [...config.rules];
		return [config];
	}
	normalizeFilterPatterns(filter) {
		if (typeof filter === "string") return [filter];
		return [...filter];
	}
	/**
	* Glob: only `*` is special (matches any substring). A lone `*` matches all namespaces.
	*/
	compileGlobPattern(pattern) {
		const trimmed = pattern.trim();
		if (trimmed === "*") return /^.*$/;
		let body = "";
		for (const ch of trimmed) {
			if (ch === "*") {
				body += ".*";
				continue;
			}
			if (globRegexMetaChars.has(ch)) {
				body += "\\" + ch;
				continue;
			}
			body += ch;
		}
		return /* @__PURE__ */ new RegExp("^" + body + "$");
	}
	parseRuleLevel(level) {
		const normalized = level.toLowerCase();
		if (normalized === "silent" || normalized === "debug" || normalized === "info" || normalized === "warn" || normalized === "error") return normalized;
		throw new Error(`Invalid codemation.config log level: ${level}`);
	}
	levelPassesAgainstMin(level, min) {
		if (min === "silent") return false;
		return levelRank[level] >= levelRank[min];
	}
};

//#endregion
//#region src/infrastructure/logging/LogLevelPolicyFactory.ts
/**
* Process-wide {@link LogLevelPolicy} singleton for server and browser loggers.
* Plain class (no `@injectable` from `@codemation/core`): client components import this file; decorating would pull core into the browser bundle.
*/
var LogLevelPolicyFactory = class {
	policy = new LogLevelPolicy();
	create() {
		return this.policy;
	}
};
/** Shared factory for call sites outside the DI container (e.g. next-host bootstrap). */
const logLevelPolicyFactory = new LogLevelPolicyFactory();

//#endregion
export { logLevelPolicyFactory as n, ConsoleLogger as r, LogLevelPolicyFactory as t };
//# sourceMappingURL=LogLevelPolicyFactory-DCUzIN6G.js.map