import { getLogger as getLogger$1 } from "../../../logger.js";
import { requireProjectPermission } from "../../../middleware/projectAccess.js";
import { speakeasyOffsetLimitPagination } from "../../../utils/speakeasy.js";
import { OpenAPIHono, createRoute } from "@hono/zod-openapi";
import { CredentialReferenceApiSelectSchema, CredentialReferenceResponse, McpToolListResponse, McpToolResponse, PaginationQueryParamsSchema, TenantProjectIdParamsSchema, TenantProjectParamsSchema, ToolApiInsertSchema, ToolApiUpdateSchema, ToolStatusSchema, commonGetErrorResponses, createApiError, createTool, dbResultToMcpTool, dbResultToMcpToolSkeleton, deleteTool, generateId, getToolById, getUserScopedCredentialReference, listTools, updateTool } from "@inkeep/agents-core";
import { z as z$1 } from "zod";

//#region src/domains/manage/routes/tools.ts
const logger = getLogger$1("tools");
const app = new OpenAPIHono();
app.use("/", async (c, next) => {
	if (c.req.method === "POST") return requireProjectPermission("edit")(c, next);
	return next();
});
app.use("/:id", async (c, next) => {
	if (c.req.method === "PUT") return requireProjectPermission("edit")(c, next);
	if (c.req.method === "DELETE") return requireProjectPermission("edit")(c, next);
	return next();
});
app.openapi(createRoute({
	method: "get",
	path: "/",
	summary: "List Tools",
	operationId: "list-tools",
	tags: ["Tools"],
	request: {
		params: TenantProjectParamsSchema,
		query: PaginationQueryParamsSchema.extend({
			status: ToolStatusSchema.optional(),
			skipDiscovery: z$1.enum(["true", "false"]).optional().transform((val) => val === "true").describe("Skip MCP server discovery for faster response. Status will be \"unknown\".")
		})
	},
	responses: {
		200: {
			description: "List of tools retrieved successfully",
			content: { "application/json": { schema: McpToolListResponse } }
		},
		...commonGetErrorResponses
	},
	...speakeasyOffsetLimitPagination
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId } = c.req.valid("param");
	const { page, limit, status, skipDiscovery } = c.req.valid("query");
	let result;
	const credentialStores = c.get("credentialStores");
	const userId = c.get("userId");
	if (skipDiscovery) {
		const dbResult = await listTools(db)({
			scopes: {
				tenantId,
				projectId
			},
			pagination: {
				page,
				limit
			}
		});
		result = {
			data: dbResult.data.map((tool) => dbResultToMcpToolSkeleton(tool)),
			pagination: dbResult.pagination
		};
		return c.json(result);
	}
	if (status) {
		const dbResult = await listTools(db)({
			scopes: {
				tenantId,
				projectId
			},
			pagination: {
				page,
				limit
			}
		});
		result = {
			data: (await Promise.all(dbResult.data.map(async (tool) => await dbResultToMcpTool(tool, db, credentialStores, void 0, userId)))).filter((tool) => tool.status === status),
			pagination: dbResult.pagination
		};
	} else {
		const dbResult = await listTools(db)({
			scopes: {
				tenantId,
				projectId
			},
			pagination: {
				page,
				limit
			}
		});
		result = {
			data: await Promise.all(dbResult.data.map(async (tool) => await dbResultToMcpTool(tool, db, credentialStores, void 0, userId))),
			pagination: dbResult.pagination
		};
	}
	return c.json(result);
});
app.openapi(createRoute({
	method: "get",
	path: "/{id}",
	summary: "Get Tool",
	operationId: "get-tool",
	tags: ["Tools"],
	request: { params: TenantProjectIdParamsSchema },
	responses: {
		200: {
			description: "Tool found",
			content: { "application/json": { schema: McpToolResponse } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, id } = c.req.valid("param");
	const tool = await getToolById(db)({
		scopes: {
			tenantId,
			projectId
		},
		toolId: id
	});
	if (!tool) throw createApiError({
		code: "not_found",
		message: "Tool not found"
	});
	const credentialStores = c.get("credentialStores");
	const userId = c.get("userId");
	return c.json({ data: await dbResultToMcpTool(tool, db, credentialStores, void 0, userId) });
});
app.openapi(createRoute({
	method: "post",
	path: "/",
	summary: "Create Tool",
	operationId: "create-tool",
	tags: ["Tools"],
	request: {
		params: TenantProjectParamsSchema,
		body: { content: { "application/json": { schema: ToolApiInsertSchema } } }
	},
	responses: {
		201: {
			description: "Tool created successfully",
			content: { "application/json": { schema: McpToolResponse } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId } = c.req.valid("param");
	const body = c.req.valid("json");
	const credentialStores = c.get("credentialStores");
	const userId = c.get("userId");
	logger.info({ body }, "body");
	const id = body.id || generateId();
	const tool = await createTool(db)({
		tenantId,
		projectId,
		id,
		name: body.name,
		config: body.config,
		credentialReferenceId: body.credentialReferenceId,
		credentialScope: body.credentialScope,
		imageUrl: body.imageUrl,
		headers: body.headers,
		isWorkApp: body.isWorkApp
	});
	return c.json({ data: await dbResultToMcpTool(tool, db, credentialStores, void 0, userId) }, 201);
});
app.openapi(createRoute({
	method: "put",
	path: "/{id}",
	summary: "Update Tool",
	operationId: "update-tool",
	tags: ["Tools"],
	request: {
		params: TenantProjectIdParamsSchema,
		body: { content: { "application/json": { schema: ToolApiUpdateSchema } } }
	},
	responses: {
		200: {
			description: "Tool updated successfully",
			content: { "application/json": { schema: McpToolResponse } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, id } = c.req.valid("param");
	const body = c.req.valid("json");
	const credentialStores = c.get("credentialStores");
	const userId = c.get("userId");
	if (Object.keys(body).length === 0) throw createApiError({
		code: "bad_request",
		message: "No fields to update"
	});
	const updatedTool = await updateTool(db)({
		scopes: {
			tenantId,
			projectId
		},
		toolId: id,
		data: {
			name: body.name,
			config: body.config,
			credentialReferenceId: body.credentialReferenceId,
			credentialScope: body.credentialScope,
			imageUrl: body.imageUrl,
			headers: body.headers,
			isWorkApp: body.isWorkApp
		}
	});
	if (!updatedTool) throw createApiError({
		code: "not_found",
		message: "Tool not found"
	});
	return c.json({ data: await dbResultToMcpTool(updatedTool, db, credentialStores, void 0, userId) });
});
app.openapi(createRoute({
	method: "get",
	path: "/{id}/user-credential",
	summary: "Get User Credential for Tool",
	operationId: "get-user-credential-for-tool",
	tags: ["Tools"],
	request: { params: TenantProjectIdParamsSchema },
	responses: {
		200: {
			description: "User credential retrieved successfully",
			content: { "application/json": { schema: CredentialReferenceResponse } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const { tenantId, projectId, id: toolId } = c.req.valid("param");
	const db = c.get("db");
	const userId = c.get("userId");
	if (!userId) throw createApiError({
		code: "unauthorized",
		message: "User ID required for user-scoped credential lookup"
	});
	const credential = await getUserScopedCredentialReference(db)({
		scopes: {
			tenantId,
			projectId
		},
		toolId,
		userId
	});
	if (!credential) throw createApiError({
		code: "not_found",
		message: "User credential not found for this tool"
	});
	const validatedCredential = CredentialReferenceApiSelectSchema.parse(credential);
	return c.json({ data: validatedCredential });
});
app.openapi(createRoute({
	method: "delete",
	path: "/{id}",
	summary: "Delete Tool",
	operationId: "delete-tool",
	tags: ["Tools"],
	request: { params: TenantProjectIdParamsSchema },
	responses: {
		204: { description: "Tool deleted successfully" },
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, id } = c.req.valid("param");
	if (!await deleteTool(db)({
		scopes: {
			tenantId,
			projectId
		},
		toolId: id
	})) throw createApiError({
		code: "not_found",
		message: "Tool not found"
	});
	return c.body(null, 204);
});
var tools_default = app;

//#endregion
export { tools_default as default };