import { logger } from "../logger/index.mjs";
import { createHmac } from "node:crypto";
import { Octokit } from "@octokit/rest";

//#region src/services/webhook.service.ts
/**
* Main entry point to trigger all configured CI pipelines for a project
*/
const triggerAll = async (project) => {
	const results = [];
	if (project.repository && project.webhooks?.autoTriggerBuilds) try {
		await triggerGitPipeline(project);
		results.push({
			target: project.repository.provider,
			success: true
		});
	} catch (error) {
		logger.error(`Failed to trigger ${project.repository.provider}`, error);
		results.push({
			target: project.repository.provider,
			success: false,
			message: error.message || String(error)
		});
	}
	const webhooks = project.webhooks?.webhooks || [];
	for (const hook of webhooks) {
		if (!hook.enabled) continue;
		try {
			await triggerGenericWebhook(hook);
			results.push({
				target: hook.name,
				success: true
			});
		} catch (error) {
			logger.error(`Failed to trigger webhook ${hook.name}`, error);
			results.push({
				target: hook.name,
				success: false,
				message: error.message || String(error)
			});
		}
	}
	return results;
};
/**
* Triggers a single webhook by index
*/
const triggerSingleWebhook = async (project, webhookIndex) => {
	const webhooks = project.webhooks?.webhooks || [];
	if (webhookIndex < 0 || webhookIndex >= webhooks.length) throw new Error(`Webhook index ${webhookIndex} is out of range`);
	const hook = webhooks[webhookIndex];
	if (!hook.enabled) throw new Error(`Webhook "${hook.name}" is disabled`);
	try {
		await triggerGenericWebhook(hook);
		return {
			target: hook.name,
			success: true
		};
	} catch (error) {
		logger.error(`Failed to trigger webhook ${hook.name}`, error);
		return {
			target: hook.name,
			success: false,
			message: error.message || String(error)
		};
	}
};
const triggerGitPipeline = async (project) => {
	const { repository, oAuth2Access } = project;
	if (!repository) throw new Error("No repository configured");
	const token = oAuth2Access?.[0]?.accessToken?.[0];
	if (!token) throw new Error("No valid OAuth token found");
	const { provider } = repository;
	switch (provider) {
		case "github": return triggerGithub(repository, token);
		case "gitlab": return triggerGitlab(repository, token);
		case "bitbucket": return triggerBitbucket(repository, token);
		default: throw new Error(`Unknown provider: ${provider}`);
	}
};
const triggerGithub = async (repo, token) => {
	await new Octokit({ auth: token }).repos.createDispatchEvent({
		owner: repo.owner,
		repo: repo.repository,
		event_type: "intlayer_cms_update",
		client_payload: {
			timestamp: (/* @__PURE__ */ new Date()).toISOString(),
			source: "intlayer-cms"
		}
	});
	logger.info(`Successfully triggered GitHub Action for ${repo.owner}/${repo.repository}`);
};
const triggerGitlab = async (repo, token) => {
	const projectId = encodeURIComponent(`${repo.owner}/${repo.repository}`);
	const branch = repo.branch || "main";
	const url = `${repo.instanceUrl || "https://gitlab.com"}/api/v4/projects/${projectId}/trigger/pipeline`;
	const formData = new FormData();
	formData.append("token", token);
	formData.append("ref", branch);
	formData.append("variables[INTLAYER_UPDATE]", "true");
	const res = await fetch(url, {
		method: "POST",
		body: formData
	});
	if (!res.ok) {
		const errorText = await res.text();
		throw new Error(`GitLab error: ${res.status} - ${errorText}`);
	}
	logger.info(`Successfully triggered GitLab pipeline for ${repo.owner}/${repo.repository}`);
};
const triggerBitbucket = async (repo, token) => {
	const workspace = repo.workspace || repo.owner;
	const branch = repo.branch || "main";
	const url = `https://api.bitbucket.org/2.0/repositories/${workspace}/${repo.repository}/pipelines/`;
	const body = {
		target: {
			ref_type: "branch",
			type: "pipeline_ref_target",
			ref_name: branch
		},
		variables: [{
			key: "INTLAYER_UPDATE",
			value: "true",
			secured: false
		}]
	};
	const res = await fetch(url, {
		method: "POST",
		headers: {
			Authorization: `Bearer ${token}`,
			"Content-Type": "application/json"
		},
		body: JSON.stringify(body)
	});
	if (!res.ok) {
		const errorText = await res.text();
		throw new Error(`Bitbucket error: ${res.status} - ${errorText}`);
	}
	logger.info(`Successfully triggered Bitbucket pipeline for ${workspace}/${repo.repository}`);
};
const triggerGenericWebhook = async (hook) => {
	const headers = { "Content-Type": "application/json" };
	if (hook.secret) {
		const payload = JSON.stringify({ event: "intlayer_cms_update" });
		headers["X-Intlayer-Signature"] = createHmac("sha256", hook.secret).update(payload).digest("hex");
	}
	const res = await fetch(hook.url, {
		method: "POST",
		headers,
		body: JSON.stringify({
			event: "intlayer_cms_update",
			timestamp: (/* @__PURE__ */ new Date()).toISOString()
		})
	});
	if (!res.ok) {
		const errorText = await res.text();
		throw new Error(`Webhook ${hook.name} failed: ${res.status} - ${errorText}`);
	}
	logger.info(`Successfully triggered webhook: ${hook.name}`);
};

//#endregion
export { triggerAll, triggerSingleWebhook };
//# sourceMappingURL=webhook.service.mjs.map