import { getLogger } from "./logger.js";
import { extractBearerToken, signJwt, verifyJwt } from "./jwt-helpers.js";

//#region src/utils/service-token-auth.ts
const logger = getLogger("service-token-auth");
const ISSUER = "inkeep-agents";
/**
* Generate a JWT token for agent-to-agent authentication.
* Token expires in 1 hour.
*/
async function generateServiceToken(params) {
	try {
		const token = await signJwt({
			issuer: ISSUER,
			subject: params.originAgentId,
			audience: params.targetAgentId,
			expiresIn: "1h",
			claims: {
				tenantId: params.tenantId,
				projectId: params.projectId,
				...params.initiatedBy ? { initiatedBy: params.initiatedBy } : {},
				...params.appId ? { appId: params.appId } : {}
			}
		});
		logger.debug({
			originAgentId: params.originAgentId,
			targetAgentId: params.targetAgentId,
			tenantId: params.tenantId
		}, "Generated team agent token");
		return token;
	} catch (error) {
		logger.error({ error }, "Failed to generate service token");
		throw new Error("Failed to generate service token");
	}
}
/**
* Verify and decode a service JWT token
*/
async function verifyServiceToken(token) {
	const result = await verifyJwt(token, { issuer: ISSUER });
	if (!result.valid || !result.payload) {
		logger.warn({ error: result.error }, "Team agent token verification failed");
		return {
			valid: false,
			error: result.error
		};
	}
	const payload = result.payload;
	if (typeof payload.sub !== "string" || typeof payload.aud !== "string" || typeof payload.tenantId !== "string" || typeof payload.projectId !== "string") {
		logger.warn({ payload }, "Invalid service token: missing required claims");
		return {
			valid: false,
			error: "Invalid token: missing required claims"
		};
	}
	const initiatedBy = payload.initiatedBy && typeof payload.initiatedBy === "object" && "type" in payload.initiatedBy && "id" in payload.initiatedBy && (payload.initiatedBy.type === "user" || payload.initiatedBy.type === "api_key") && typeof payload.initiatedBy.id === "string" ? payload.initiatedBy : void 0;
	const appId = typeof payload.appId === "string" ? payload.appId : void 0;
	const validPayload = {
		iss: payload.iss,
		aud: payload.aud,
		sub: payload.sub,
		tenantId: payload.tenantId,
		projectId: payload.projectId,
		...initiatedBy ? { initiatedBy } : {},
		...appId ? { appId } : {},
		iat: payload.iat,
		exp: payload.exp
	};
	logger.debug({
		originAgentId: validPayload.sub,
		targetAgentId: validPayload.aud,
		tenantId: validPayload.tenantId
	}, "Successfully verified team agent token");
	return {
		valid: true,
		payload: validPayload
	};
}
/**
* Validate that the token's tenant ID matches the expected tenant.
* This prevents cross-tenant delegation attempts.
*/
function validateTenantId(payload, expectedTenantId) {
	if (payload.tenantId !== expectedTenantId) {
		logger.warn({
			tokenTenantId: payload.tenantId,
			expectedTenantId,
			originAgentId: payload.sub,
			targetAgentId: payload.aud
		}, "Cross-tenant delegation attempt detected");
		return false;
	}
	return true;
}
/**
* Validate that the token's target agent ID matches the expected agent
*/
function validateTargetAgent(payload, expectedTargetAgentId) {
	if (payload.aud !== expectedTargetAgentId) {
		logger.warn({
			tokenTargetAgentId: payload.aud,
			expectedTargetAgentId,
			originAgentId: payload.sub
		}, "Token target agent mismatch");
		return false;
	}
	return true;
}
/**
* Extract the Authorization header and verify the bearer token
*/
async function verifyAuthorizationHeader(authHeader) {
	const extracted = extractBearerToken(authHeader);
	if (!extracted.token) return {
		valid: false,
		error: extracted.error
	};
	return verifyServiceToken(extracted.token);
}

//#endregion
export { generateServiceToken, validateTargetAgent, validateTenantId, verifyAuthorizationHeader, verifyServiceToken };