//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2026 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------
// The Data Extraction suite is an optional PDFNet add-on collection that can be used to
// extract various types of data from PDF documents.
//
// The Apryse SDK Data Extraction suite can be downloaded from http://www.apryse.com/
//---------------------------------------------------------------------------------------

const fs = require('fs');
const { PDFNet } = require('@pdftron/pdfnet-node');
const PDFTronLicense = require('../LicenseKey/LicenseKey');

((exports) => {
	'use strict';

	exports.runDataExtractionTest = () => {

		const main = async () => {

			const inputPath = '../TestFiles/';
			const outputPath = '../TestFiles/Output/';

			//////////////////////////////////////////////////////////////////////////

			await PDFNet.addResourceSearchPath('../Lib/');

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract tables from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK Tabular Data module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Extract tabular data as a JSON file
					console.log('Extract tabular data as a JSON file');

					let outputFile = outputPath + 'table.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'table.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract tabular data as a JSON string
					console.log('Extract tabular data as a JSON string');

					outputFile = outputPath + 'financial.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'financial.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_Tabular);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract tabular data as an XLSX file
					console.log('Extract tabular data as an XLSX file');

					outputFile = outputPath + 'table.xlsx';
					await PDFNet.DataExtractionModule.extractToXLSX(inputPath + 'table.pdf', outputFile);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract tabular data as an XLSX stream (also known as filter)
					console.log('Extract tabular data as an XLSX stream');

					outputFile = outputPath + 'financial.xlsx';
					const outputXlsxStream = await PDFNet.Filter.createMemoryFilter(0, false);
					const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
					options.setPages('1'); // page 1
					await PDFNet.DataExtractionModule.extractToXLSXWithFilter(inputPath + 'financial.pdf', outputXlsxStream, options);
					outputXlsxStream.memoryFilterSetAsInputFilter();
					outputXlsxStream.writeToFile(outputFile, false);

					console.log('Result saved in ' + outputFile);
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract document structure from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK Structured Output module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Extract document structure as a JSON file
					console.log('Extract document structure as a JSON file');

					let outputFile = outputPath + 'paragraphs_and_tables.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'paragraphs_and_tables.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract document structure as a JSON string
					console.log('Extract document structure as a JSON string');

					outputFile = outputPath + 'tagged.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'tagged.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_DocStructure);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract form fields from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_Form)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK AIFormFieldExtractor module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Extract form fields as a JSON file
					console.log('Extract form fields as a JSON file');

					let outputFile = outputPath + 'formfields-scanned.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'formfields-scanned.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_Form);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Extract form fields as a JSON string
					console.log('Extract form fields as a JSON string');

					outputFile = outputPath + 'formfields.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'formfields.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_Form);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);

					//////////////////////////////////////////////////////////////////////////
					// Detect and add form fields to a PDF document.
					// Document already has form fields, and this sample will update to new found fields.
					{
						console.log('Detect and add form fields in a PDF file, keep new fields');

						const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'formfields-scanned-withfields.pdf');

						await PDFNet.DataExtractionModule.detectAndAddFormFieldsToPDF(doc);
						outputFile = outputPath + 'formfields-scanned-fields-new.pdf';
						await doc.save(outputFile, PDFNet.SDFDoc.SaveOptions.e_linearized);

						console.log('Result saved in ' + outputFile);
					}

					//////////////////////////////////////////////////////////////////////////
					// Detect and add form fields to a PDF document.
					// Document already has form fields, and this sample will keep the original fields.
					{
						console.log('Detect and add form fields in a PDF file, keep old fields');

						const doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'formfields-scanned-withfields.pdf');

						const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
						options.setOverlappingFormFieldBehavior('KeepOld');

						await PDFNet.DataExtractionModule.detectAndAddFormFieldsToPDF(doc, options);
						outputFile = outputPath + 'formfields-scanned-fields-old.pdf';
						await doc.save(outputFile, PDFNet.SDFDoc.SaveOptions.e_linearized);
					}

					console.log('Result saved in ' + outputFile);

				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract key-value pairs from PDF documents.
			//////////////////////////////////////////////////////////////////////////
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue)) {
				console.log();
				console.log('Unable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at http://www.apryse.com/. If you have already downloaded this');
				console.log('module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.');
				console.log();
			}
			else
			{
				try {
					// Simple example: Extract Keys & Values as a JSON file
					console.log('Extract Key-Value pairs as a JSON file');
					await PDFNet.DataExtractionModule.extractData(inputPath + 'newsletter.pdf', outputPath + 'newsletter_key_val.json', PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue);
					console.log('Result saved in ' + outputPath + 'newsletter_key_val.json');
					
					const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
					options.setPages('2-4');
				
					const p2ExclusionZones = [];
					// Exclude the ad on page 2
					// These coordinates are in PDF user space, with the origin at the bottom left corner of the page
					// Coordinates rotate with the page, if it has rotation applied.
					p2ExclusionZones.push(new PDFNet.Rect(166, 47, 562, 222));
					options.addExclusionZonesForPage(p2ExclusionZones, 2);
				
					const p4InclusionZones = [];
					const p4ExclusionZones = [];
					// Only include the article text for page 4, exclude ads and headings
					p4InclusionZones.push(new PDFNet.Rect(30, 432, 562, 684));
					p4ExclusionZones.push(new PDFNet.Rect(30, 657, 295, 684));
					options.addInclusionZonesForPage(p4InclusionZones, 4);
					options.addExclusionZonesForPage(p4ExclusionZones, 4);
					console.log('Extract Key-Value pairs from specific pages and zones as a JSON file');
					await PDFNet.DataExtractionModule.extractData(inputPath + 'newsletter.pdf', outputPath + 'newsletter_key_val_with_zones.json', PDFNet.DataExtractionModule.DataExtractionEngine.e_GenericKeyValue, options);
					console.log('Result saved in ' + outputPath + 'newsletter_key_val_with_zones.json');
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////
			// The following sample illustrates how to extract document classes from PDF documents.
			//////////////////////////////////////////////////////////////////////////

			// Test if the add-on is installed
			if (!await PDFNet.DataExtractionModule.isModuleAvailable(PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification)) {
				console.log('\nUnable to run Data Extraction: Apryse SDK AIPageObjectExtractor module not available.');
				console.log('---------------------------------------------------------------');
				console.log('The Data Extraction suite is an optional add-on, available for download');
				console.log('at https://docs.apryse.com/documentation/core/info/modules/. If you have already');
				console.log('downloaded this module, ensure that the SDK is able to find the required files');
				console.log('using the PDFNet.addResourceSearchPath() function.\n');
			}
			else
			{
				try {
					// Simple example: classify pages as a JSON file
					console.log('Classify pages as a JSON file');

					let outputFile = outputPath + 'Invoice_Classified.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'Invoice.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification);

					console.log('Result saved in ' + outputFile);

					///////////////////////////////////////////////////////
					// Classify pages as a JSON string
					console.log('Classify pages as a JSON string');

					outputFile = outputPath + 'Scientific_Publication_Classified.json';
					const json = await PDFNet.DataExtractionModule.extractDataAsString(inputPath + 'Scientific_Publication.pdf', PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification);
					fs.writeFileSync(outputFile, json);

					console.log('Result saved in ' + outputFile);
					
					///////////////////////////////////////////////////////
					// Example with customized options:
					console.log('Classify pages with customized options');

					const options = new PDFNet.DataExtractionModule.DataExtractionOptions();
					// Classes that don't meet the minimum confidence threshold of 70% will not be listed in the output JSON
					options.setMinimumConfidenceThreshold(0.7);
					outputFile = outputPath + 'Email_Classified.json';
					await PDFNet.DataExtractionModule.extractData(inputPath + 'Email.pdf', outputFile, PDFNet.DataExtractionModule.DataExtractionEngine.e_DocClassification, options);

					console.log('Result saved in ' + outputFile);
					
				} catch (err) {
					console.log(err);
				}
			}

			//////////////////////////////////////////////////////////////////////////

			console.log('Done.');
		};

		PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function (error) {
			console.log('Error: ' + JSON.stringify(error));
		}).then(function () { return PDFNet.shutdown(); });
	};
	exports.runDataExtractionTest();
})(exports);
// eslint-disable-next-line spaced-comment
//# sourceURL=DataExtractionTest.js
