import runDbClient_default from "../../../data/db/runDbClient.js";
import { requireProjectPermission } from "../../../middleware/projectAccess.js";
import { OpenAPIHono, z } from "@hono/zod-openapi";
import { BranchListResponseSchema, BranchNameParamsSchema, BranchResponseSchema, CreateBranchRequestSchema, ErrorResponseSchema, TenantProjectAgentParamsSchema, TenantProjectParamsSchema, cascadeDeleteByBranch, commonGetErrorResponses, createApiError, createBranch, deleteBranch, getBranch, invalidBranchParamsError, listBranches, listBranchesForAgent, throwIfUniqueConstraintError } from "@inkeep/agents-core";
import { createProtectedRoute } from "@inkeep/agents-core/middleware";

//#region src/domains/manage/routes/branches.ts
const app = new OpenAPIHono();
app.openapi(createProtectedRoute({
	method: "get",
	path: "/",
	summary: "List Branches",
	description: "List all branches within a project",
	operationId: "list-branches",
	tags: ["Branches"],
	permission: requireProjectPermission("view"),
	request: { params: TenantProjectParamsSchema },
	responses: {
		200: {
			description: "List of branches retrieved successfully",
			content: { "application/json": { schema: BranchListResponseSchema } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId } = c.req.valid("param");
	const branches = await listBranches(db)({
		tenantId,
		projectId
	});
	return c.json({ data: branches });
});
app.openapi(createProtectedRoute({
	method: "get",
	path: "/{branchName}",
	summary: "Get Branch",
	description: "Get a single branch by name",
	operationId: "get-branch",
	tags: ["Branches"],
	permission: requireProjectPermission("view"),
	request: { params: BranchNameParamsSchema },
	responses: {
		200: {
			description: "Branch found",
			content: { "application/json": { schema: BranchResponseSchema } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, branchName } = c.req.valid("param");
	const branch = await getBranch(db)({
		tenantId,
		projectId,
		name: branchName
	});
	if (!branch) throw createApiError({
		code: "not_found",
		message: `Branch '${branchName}' not found`
	});
	return c.json({ data: branch });
});
app.openapi(createProtectedRoute({
	method: "get",
	path: "/agents/{agentId}",
	summary: "List Branches for Agent",
	description: "List all branches within a project that contain the agent",
	operationId: "list-branches-for-agent",
	tags: ["Branches"],
	permission: requireProjectPermission("view"),
	request: { params: TenantProjectAgentParamsSchema },
	responses: {
		200: {
			description: "List of branches retrieved successfully",
			content: { "application/json": { schema: BranchListResponseSchema } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, agentId } = c.req.valid("param");
	const branches = await listBranchesForAgent(db)({
		tenantId,
		projectId,
		agentId
	});
	return c.json({ data: branches });
});
app.openapi(createProtectedRoute({
	method: "post",
	path: "/",
	summary: "Create Branch",
	description: "Create a new branch",
	operationId: "create-branch",
	tags: ["Branches"],
	permission: requireProjectPermission("edit"),
	request: {
		params: TenantProjectParamsSchema,
		body: { content: { "application/json": { schema: CreateBranchRequestSchema } } }
	},
	responses: {
		201: {
			description: "Branch created successfully",
			content: { "application/json": { schema: BranchResponseSchema } }
		},
		409: {
			description: "Branch already exists",
			content: { "application/json": { schema: ErrorResponseSchema } }
		},
		...commonGetErrorResponses
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId } = c.req.valid("param");
	const { name, fromBranch, fromCommit } = c.req.valid("json");
	try {
		const branch = await createBranch(db)({
			tenantId,
			projectId,
			name,
			fromBranch,
			fromCommit
		});
		return c.json({ data: branch }, 201);
	} catch (error) {
		const message = error?.message || "Unknown error";
		throwIfUniqueConstraintError(error, `Branch '${name}' already exists`);
		if (error instanceof invalidBranchParamsError) throw createApiError({
			code: "bad_request",
			message
		});
		throw error;
	}
});
app.openapi(createProtectedRoute({
	method: "delete",
	path: "/{branchName}",
	summary: "Delete Branch",
	description: "Delete a branch. Cannot delete protected branches like main.",
	operationId: "delete-branch",
	tags: ["Branches"],
	permission: requireProjectPermission("edit"),
	request: {
		params: BranchNameParamsSchema,
		query: z.object({ force: z.enum(["true", "false"]).optional().default("false").transform((v) => v === "true").openapi({ param: {
			name: "force",
			in: "query"
		} }) })
	},
	responses: {
		204: { description: "Branch deleted successfully" },
		...commonGetErrorResponses,
		403: {
			description: "Cannot delete protected branch",
			content: { "application/json": { schema: ErrorResponseSchema } }
		}
	}
}), async (c) => {
	const db = c.get("db");
	const { tenantId, projectId, branchName } = c.req.valid("param");
	const { force } = c.req.valid("query");
	try {
		const fullBranchName = `${tenantId}_${projectId}_${branchName}`;
		await cascadeDeleteByBranch(runDbClient_default)({
			scopes: {
				tenantId,
				projectId
			},
			fullBranchName,
			ref: branchName
		});
		await deleteBranch(db)({
			tenantId,
			projectId,
			branchName,
			force
		});
		return c.body(null, 204);
	} catch (error) {
		const message = error?.message || "Unknown error";
		if (message.includes("protected branch")) throw createApiError({
			code: "forbidden",
			message
		});
		if (message.includes("not found")) throw createApiError({
			code: "not_found",
			message: `Branch '${branchName}' not found`
		});
		throw error;
	}
});
var branches_default = app;

//#endregion
export { branches_default as default };