import { requireGatewayMicroservicesForWorker } from './gateway-rails-enforcement';

const DEFAULT_PREFIX = 'dbis.gateway.';

/**
 * Queue names matching this prefix (or `SOLACENET_GATEWAY_MQ_QUEUE_PREFIX`) run
 * `requireGatewayMicroservicesForWorker` before the handler when enforcement is on.
 */
export function gatewayMqQueueNeedsSolaceNetCheck(queueName: string): boolean {
	const prefix = process.env.SOLACENET_GATEWAY_MQ_QUEUE_PREFIX?.trim() || DEFAULT_PREFIX;
	return queueName.startsWith(prefix);
}

export function resolveTenantIdFromMqMessage(message: unknown): string {
	if (message && typeof message === 'object') {
		const m = message as Record<string, unknown>;
		const direct = m.tenantId;
		if (typeof direct === 'string' && direct.length > 0) return direct;
		const body = m.body;
		if (body && typeof body === 'object') {
			const b = body as Record<string, unknown>;
			if (typeof b.tenantId === 'string' && b.tenantId.length > 0) return b.tenantId;
		}
	}
	return process.env.SOLACENET_DEFAULT_TENANT_ID || 'system';
}

/**
 * Wrap a RabbitMQ/Kafka-style handler so SolaceNet gateway enforcement applies
 * to gateway-prefixed queues. Use when wiring real `subscribeToQueue` consumers.
 */
export function wrapGatewayMqMessageHandler(
	queueName: string,
	handler: (message: unknown) => Promise<void>,
): (message: unknown) => Promise<void> {
	if (!gatewayMqQueueNeedsSolaceNetCheck(queueName)) {
		return handler;
	}
	return async (message: unknown) => {
		const tenantId = resolveTenantIdFromMqMessage(message);
		const adapterId =
			message && typeof message === 'object' && typeof (message as Record<string, unknown>).adapterId === 'string'
				? String((message as Record<string, unknown>).adapterId)
				: undefined;
		await requireGatewayMicroservicesForWorker({
			tenantId,
			ingressKind: 'mq',
			detail: queueName,
			adapterId,
		});
		await handler(message);
	};
}
