import { IronPdfServiceClient } from "../../generated_proto/ironpdfengineproto/IronPdfService";
import { Access } from "../../access";
import {
	handleEmptyResultP__Output,
	handlePdfDocumentResultP__Output,
	handleRemoteException,
} from "../util";
import { PdfPermission } from "../../../public/security";
import {
	convertPermissionsInterfaceToEnum,
	pdfPermissionFromProto
} from "./converter";
import { PdfiumPdfSecuritySettingsP__Output } from "../../generated_proto/ironpdfengineproto/PdfiumPdfSecuritySettingsP";
import { PdfiumGetPdfSecuritySettingsResultP__Output } from "../../generated_proto/ironpdfengineproto/PdfiumGetPdfSecuritySettingsResultP";

export async function removePasswordsAndEncryption(id: string): Promise<void> {
	const client: IronPdfServiceClient = await Access.ensureConnection();
	return new Promise<void>(
		(resolve: () => void, reject: (errorMsg: string) => void) => {
			client.pdfiumSecurityRemovePasswordsAndEncryption(
				{
					document: { documentId: id },
				},
				(err, value) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handleEmptyResultP__Output(value, reject);
						resolve();
					}
				}
			);
		}
	);
}

export async function setUserPasswords(
	id: string,
	password: string
): Promise<string> {
	const client: IronPdfServiceClient = await Access.ensureConnection();

	const oldPermission = await getPermission_Inner(id);

	return new Promise<string>(
		(resolve: (_: string) => void, reject: (errorMsg: string) => void) => {
			client.pdfiumSecuritySetPdfSecuritySettings(
				{
					document: { documentId: id },
					settings: {
						userPassword: password,
						ownerPassword: oldPermission.ownerPassword ?? "",
						permissions: oldPermission.permissions ?? null,
					},
				},
				(err, value) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handlePdfDocumentResultP__Output(
							value,
							resolve,
							reject
						);
					}
				}
			);
		}
	);
}

export async function setOwnerPasswords(
	id: string,
	password: string
): Promise<string> {
	const client: IronPdfServiceClient = await Access.ensureConnection();

	const oldPermission = await getPermission_Inner(id);

	return new Promise<string>(
		(resolve: (_: string) => void, reject: (errorMsg: string) => void) => {
			client.pdfiumSecuritySetPdfSecuritySettings(
				{
					document: { documentId: id },
					settings: {
						userPassword: oldPermission.userPassword ?? "",
						ownerPassword: password,
						permissions: oldPermission.permissions ?? null,
					},
				},
				(err, value) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handlePdfDocumentResultP__Output(
							value,
							resolve,
							reject
						);
					}
				}
			);
		}
	);
}

export async function setSecurity(
	id: string,
	pdfPermission: PdfPermission
): Promise<string> {
	const client: IronPdfServiceClient = await Access.ensureConnection();

	const oldPermission = await getPermission_Inner(id);

	return new Promise<string>(
		(resolve: (_: string) => void, reject: (errorMsg: string) => void) => {
			client.pdfiumSecuritySetPdfSecuritySettings(
				{
					document: { documentId: id },
					settings: {
						userPassword: oldPermission.userPassword ?? "",
						ownerPassword: oldPermission.ownerPassword ?? "",
						permissions: {enumValue:convertPermissionsInterfaceToEnum(pdfPermission)} ,
					},
				},
				(err, value) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						handlePdfDocumentResultP__Output(
							value,
							resolve,
							reject
						);
					}
				}
			);
		}
	);
}
export async function getPermission_Inner(
	id: string
): Promise<PdfiumPdfSecuritySettingsP__Output> {
	const client: IronPdfServiceClient = await Access.ensureConnection();
	return new Promise<PdfiumPdfSecuritySettingsP__Output>(
		(
			resolve: (_: PdfiumPdfSecuritySettingsP__Output) => void,
			reject: (errorMsg: string) => void
		) => {
			client.pdfiumSecurityGetPdfSecuritySettings(
				{
					document: { documentId: id },
				},
				(err, value) => {
					if (err) {
						reject(`${err.name}/n${err.message}`);
					} else if (value) {
						resolve(
							handlePdfiumGetPdfSecuritySettingsResultP__Output(
								value,
								reject
							)
						);
					}
				}
			);
		}
	);
}

export async function getPermission(id: string): Promise<PdfPermission> {
	const p = await getPermission_Inner(id);
	return pdfPermissionFromProto(p.permissions!);
}

export function handlePdfiumGetPdfSecuritySettingsResultP__Output(
	proto: PdfiumGetPdfSecuritySettingsResultP__Output | undefined,
	reject: (errorMsg: string) => void
): PdfiumPdfSecuritySettingsP__Output {
	if (proto) {
		if (proto.exception) {
			handleRemoteException(proto.exception, reject);
		}
		if (proto.securitySettings) {
			return proto.securitySettings;
		}
	}
	throw new Error("Error empty message");
}
