//#region extensions/zalouser/src/doctor-contract.ts
function asObjectRecord(value) {
	return value && typeof value === "object" && !Array.isArray(value) ? value : null;
}
function hasLegacyZalouserGroupAllowAlias(value) {
	const group = asObjectRecord(value);
	return Boolean(group && typeof group.allow === "boolean");
}
function hasLegacyZalouserGroupAllowAliases(value) {
	const groups = asObjectRecord(value);
	return Boolean(groups && Object.values(groups).some((group) => hasLegacyZalouserGroupAllowAlias(group)));
}
function hasLegacyZalouserAccountGroupAllowAliases(value) {
	const accounts = asObjectRecord(value);
	if (!accounts) return false;
	return Object.values(accounts).some((account) => {
		const accountRecord = asObjectRecord(account);
		return Boolean(accountRecord && hasLegacyZalouserGroupAllowAliases(accountRecord.groups));
	});
}
function normalizeZalouserGroupAllowAliases(params) {
	let changed = false;
	const nextGroups = { ...params.groups };
	for (const [groupId, groupValue] of Object.entries(params.groups)) {
		const group = asObjectRecord(groupValue);
		if (!group || typeof group.allow !== "boolean") continue;
		const nextGroup = { ...group };
		if (typeof nextGroup.enabled !== "boolean") nextGroup.enabled = group.allow;
		delete nextGroup.allow;
		nextGroups[groupId] = nextGroup;
		changed = true;
		params.changes.push(`Moved ${params.pathPrefix}.${groupId}.allow → ${params.pathPrefix}.${groupId}.enabled (${String(nextGroup.enabled)}).`);
	}
	return {
		groups: nextGroups,
		changed
	};
}
function normalizeZalouserCompatibilityConfig(cfg) {
	const zalouser = asObjectRecord(asObjectRecord(cfg.channels)?.zalouser);
	if (!zalouser) return {
		config: cfg,
		changes: []
	};
	const changes = [];
	let updatedZalouser = zalouser;
	let changed = false;
	const groups = asObjectRecord(updatedZalouser.groups);
	if (groups) {
		const normalized = normalizeZalouserGroupAllowAliases({
			groups,
			pathPrefix: "channels.zalouser.groups",
			changes
		});
		if (normalized.changed) {
			updatedZalouser = {
				...updatedZalouser,
				groups: normalized.groups
			};
			changed = true;
		}
	}
	const accounts = asObjectRecord(updatedZalouser.accounts);
	if (accounts) {
		let accountsChanged = false;
		const nextAccounts = { ...accounts };
		for (const [accountId, accountValue] of Object.entries(accounts)) {
			const account = asObjectRecord(accountValue);
			if (!account) continue;
			const accountGroups = asObjectRecord(account.groups);
			if (!accountGroups) continue;
			const normalized = normalizeZalouserGroupAllowAliases({
				groups: accountGroups,
				pathPrefix: `channels.zalouser.accounts.${accountId}.groups`,
				changes
			});
			if (!normalized.changed) continue;
			nextAccounts[accountId] = {
				...account,
				groups: normalized.groups
			};
			accountsChanged = true;
		}
		if (accountsChanged) {
			updatedZalouser = {
				...updatedZalouser,
				accounts: nextAccounts
			};
			changed = true;
		}
	}
	if (!changed) return {
		config: cfg,
		changes: []
	};
	return {
		config: {
			...cfg,
			channels: {
				...cfg.channels,
				zalouser: updatedZalouser
			}
		},
		changes
	};
}
const legacyConfigRules = [{
	path: [
		"channels",
		"zalouser",
		"groups"
	],
	message: "channels.zalouser.groups.<id>.allow is legacy; use channels.zalouser.groups.<id>.enabled instead. Run \"daocore doctor --fix\".",
	match: hasLegacyZalouserGroupAllowAliases
}, {
	path: [
		"channels",
		"zalouser",
		"accounts"
	],
	message: "channels.zalouser.accounts.<id>.groups.<id>.allow is legacy; use channels.zalouser.accounts.<id>.groups.<id>.enabled instead. Run \"daocore doctor --fix\".",
	match: hasLegacyZalouserAccountGroupAllowAliases
}];
function normalizeCompatibilityConfig(params) {
	return normalizeZalouserCompatibilityConfig(params.cfg);
}
//#endregion
export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
