/*
 * Copyright 2024 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it. If you have received this file from a source other than Adobe,
 * then your use, modification, or distribution of it requires the prior
 * written permission of Adobe.
 */

const {
    ServicePrincipalCredentials,
    PDFServices,
    MimeType,
    ClientConfig,
    CreatePDFJob,
    CreatePDFResult,
    ProxyServerConfig,
    ProxyScheme,
    SDKError,
    ServiceUsageError,
    ServiceApiError
} = require("@adobe/pdfservices-node-sdk");
const fs = require("fs");

/**
 * This sample illustrates how to setup Proxy Server configurations for performing an operation. This enables the
 * clients to set proxy server configurations to enable the API calls in a network where calls are blocked unless they
 * are routed via Proxy server.
 * <p>
 * Refer to README.md for instructions on how to run the samples.
 */
(async () => {
    let readStream;
    try {
        // Initial setup, create credentials instance
        const credentials = new ServicePrincipalCredentials({
            clientId: process.env.PDF_SERVICES_CLIENT_ID,
            clientSecret: process.env.PDF_SERVICES_CLIENT_SECRET
        });

        /*
        Initial setup, creates proxy server config instance for client config.
        Replace the values of PROXY_HOSTNAME with the proxy server hostname.
        If the scheme of proxy server is not HTTP then, replace ProxyScheme parameter with HTTPS.
        If the port for proxy server is diff than the default port for HTTP and HTTPS, then please set the
        PROXY_PORT,
        else, remove its setter statement.
        */
        const proxyServerConfig = new ProxyServerConfig({
            host: "PROXY_HOSTNAME",
            port: 443,
            scheme: ProxyScheme.HTTP
        });

        // Creates client config instance
        const clientConfig = new ClientConfig({
            proxyServerConfig
        });

        // Creates a PDF Services instance
        const pdfServices = new PDFServices({credentials, clientConfig});

        // Creates an asset(s) from source file(s) and upload
        readStream = fs.createReadStream("resources/createPDFInput.docx")
        const inputAsset = await pdfServices.upload({
            readStream,
            mimeType: MimeType.DOCX
        });

        // Creates a new job instance
        const job = new CreatePDFJob({inputAsset});

        // Submit the job and get the job result
        const pollingURL = await pdfServices.submit({job});
        const pdfServicesResponse = await pdfServices.getJobResult({
            pollingURL,
            resultType: CreatePDFResult
        });

        // Get content from the resulting asset(s)
        const resultAsset = pdfServicesResponse.result.asset;
        const streamAsset = await pdfServices.getContent({asset: resultAsset});

        // Creates a write stream and copy stream asset's content to it
        const outputFilePath = createOutputFilePath();
        console.log(`Saving asset at ${outputFilePath}`);

        const writeStream = fs.createWriteStream(outputFilePath);
        streamAsset.readStream.pipe(writeStream);
    } catch (err) {
        if (err instanceof SDKError || err instanceof ServiceUsageError || err instanceof ServiceApiError) {
            console.log("Exception encountered while executing operation", err);
        } else {
            console.log("Exception encountered while executing operation", err);
        }
    } finally {
        readStream?.destroy();
    }
})();

// Generates a string containing a directory structure and file name for the output file
function createOutputFilePath() {
    const filePath = "output/CreatePDFWithProxyServer/";
    const date = new Date();
    const dateString = date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" +
        ("0" + date.getDate()).slice(-2) + "T" + ("0" + date.getHours()).slice(-2) + "-" +
        ("0" + date.getMinutes()).slice(-2) + "-" + ("0" + date.getSeconds()).slice(-2);
    fs.mkdirSync(filePath, {recursive: true});
    return (`${filePath}create${dateString}.pdf`);
}