import { doltHashOf } from "./commit.js";
import { resolveRef } from "./ref-helpers.js";
import { sql } from "drizzle-orm";
import { logger } from "@composio/core";

//#region src/dolt/branch.ts
/**
* Create a new branch
*/
const doltBranch = (db) => async (params) => {
	if (params.startPoint) {
		const startPointHash = await doltHashOf(db)({ revision: params.startPoint });
		await db.execute(sql.raw(`SELECT DOLT_BRANCH('${params.name}', '${startPointHash}')`));
	} else await db.execute(sql.raw(`SELECT DOLT_BRANCH('${params.name}')`));
};
/**
* Delete a branch
*/
const doltDeleteBranch = (db) => async (params) => {
	const flag = params.force ? "-D" : "-d";
	await db.execute(sql.raw(`SELECT DOLT_BRANCH('${flag}', '${params.name}')`));
};
/**
* Rename a branch
*/
const doltRenameBranch = (db) => async (params) => {
	await db.execute(sql.raw(`SELECT DOLT_BRANCH('-m', '${params.oldName}', '${params.newName}')`));
};
/**
* List all branches
*/
const doltListBranches = (db) => async () => {
	return (await db.execute(sql`SELECT * FROM dolt_branches`)).rows;
};
/**
* Check if a branch exists
*/
const doltBranchExists = (db) => async (params) => {
	return (await db.execute(sql.raw(`SELECT * FROM dolt_branches WHERE name = '${params.name}'`))).rows.length > 0;
};
/**
* Checkout a branch or create and checkout a new branch
*/
const doltCheckout = (db) => async (params) => {
	params.create ? await db.execute(sql.raw(`SELECT DOLT_CHECKOUT('-b', '${params.branch}')`)) : await db.execute(sql.raw(`SELECT DOLT_CHECKOUT('${params.branch}')`));
};
/**
* Get the currently active branch
*/
const doltActiveBranch = (db) => async () => {
	return (await db.execute(sql`SELECT ACTIVE_BRANCH() as branch`)).rows[0]?.branch;
};
const doltGetBranchNamespace = (scopes) => () => {
	return `${scopes.tenantId}_${scopes.projectId}_${scopes.branchName}`;
};
/**
* Create a branch if it doesn't exist, handling race conditions gracefully.
* If multiple concurrent requests try to create the same branch, only one will succeed.
*/
const ensureBranchExists = async (db, branchName) => {
	if (await resolveRef(db)(branchName)) {
		logger.debug({ branchName }, "Branch already exists, skipping creation");
		return;
	}
	try {
		await doltBranch(db)({ name: branchName });
		logger.debug({ branchName }, "Branch created successfully");
	} catch (error) {
		if (await resolveRef(db)(branchName)) {
			logger.debug({ branchName }, "Branch creation failed but branch exists (concurrent creation), continuing");
			return;
		}
		logger.error({
			branchName,
			error
		}, "Branch creation failed and branch does not exist");
		throw error;
	}
};

//#endregion
export { doltActiveBranch, doltBranch, doltBranchExists, doltCheckout, doltDeleteBranch, doltGetBranchNamespace, doltListBranches, doltRenameBranch, ensureBranchExists };