import { ServiceError } from "@grpc/grpc-js";
import { HandshakeRequestP } from "../generated_proto/ironpdfengineproto/HandshakeRequestP";
import { IronPdfGlobalConfig } from "../../public/ironpdfglobalconfig";
import { IronPdfServiceClient } from "../generated_proto/ironpdfengineproto/IronPdfService";
import { HandshakeResponseP__Output } from "../generated_proto/ironpdfengineproto/HandshakeResponseP";

const handshakeRequest: HandshakeRequestP = {
	progLang: "nodejs",
	expectedVersion: IronPdfGlobalConfig.ironPdfEngineVersion,
};

async function handshake(
	client: IronPdfServiceClient
): Promise<HandshakeResponseP__Output> {
	return new Promise(function (resolve, reject) {
		client.handshake(
			handshakeRequest,
			async (
				err: ServiceError | null,
				value: HandshakeResponseP__Output | undefined
			) => {
				if (err) {
					reject(err.name + err.message);
				} else if (value) {
					resolve(value!);
				}
			}
		);
	});
}

function retryDelay(reason: any): Promise<HandshakeResponseP__Output> {
	return new Promise(function (_resolve, reject) {
		setTimeout(reject.bind(null, reason), 4000);
	});
}

export async function handshakeWithRetry(
	client: IronPdfServiceClient,
	retryCount: number
) {
	let p: Promise<HandshakeResponseP__Output> = Promise.reject();
	for (let i = 0; i < retryCount; i++) {
		p = p.catch((_) => handshake(client)).catch((r) => {
			if (IronPdfGlobalConfig.getConfig().debugMode)
				console.log(`Waiting for IronPdfEngine is ready. (Retry ${i+1}/${retryCount})`);
			return retryDelay(r);
		});
	}
	return p;
}
