/**
 * validation_rest.js
 * version 1.0.0 (2026-06-17T01:31Z)
 * author: David Ireland <https://di-mgt.com.au/contact>
 * copyright (c) 2026 DI Management Services Pty Ltd
 * SPDX-License-Identifier: Apache-2.0
 *
 * Node.js REST client for the FirmaSAT validation service.
 * Reads XML input and optional PAC certificate data, posts them to the
 * FirmaSAT validation API, and prints the parsed JSON response.
 *
 * Usage:
 *   node validation_rest.js
 */
 
import fs from "fs";
import path from "path";

const DEBUG = false;
const DPRINT = DEBUG ? console.log : () => {};

/**
 * Validate XML data with the FirmaSAT validation REST API.
 *
 * @param {string} xmlFile - Path to the XML input file.
 * @param {string} [certFileOrString=""] - Optional PAC certificate file path,
 *   PEM/base64 certificate text file, or base64 string.
 * @returns {Promise<void>} Resolves when the validation response is printed.
 * @throws {Error} If a certificate path is missing or invalid.
 */
async function validate(xmlFile, certFileOrString = "") {
  const url = "https://di-mgt.com.au/cryptosys/api/fsa_validation";
  const apiToken = "YOUR_API_TOKEN_HERE"; // replace with your api-token
  console.log(`FILE: ${xmlFile}`);

  const encodeFileToBase64 = (filePath) => fs.readFileSync(filePath).toString('base64');
  const readTextFile = (filePath) => fs.readFileSync(filePath, 'utf8');

  const xmlContent = readTextFile(xmlFile);
  DPRINT(xmlContent);

  let certContent = "";
  if (certFileOrString) {
    if (certFileOrString.length > 250 && !fs.existsSync(certFileOrString)) {
      certContent = certFileOrString;
    } else {
      if (!fs.existsSync(certFileOrString)) {
        throw new Error(`File '${certFileOrString}' not found`);
      }
      const buf = fs.readFileSync(certFileOrString);
      const firstByte = buf[0];
      if (firstByte === 0x30) { // binary DER (starts 0x30)
        certContent = encodeFileToBase64(certFileOrString);
      } else if (firstByte === 0x4D || firstByte === 0x2D) { // 'M' or '-'
        certContent = readTextFile(certFileOrString);
      } else {
        throw new Error(`${certFileOrString} is not a valid certificate`);
      }
    }
  }

  DPRINT(certContent);

  const payload = { "api-token": apiToken, "xmldata": xmlContent, "pac-cert": certContent };

  const response = await fetch(url, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(payload),
  });

  const data = await response.json();
  if (typeof data["validation-result"] === "string") {
    data["validation-result"] = JSON.parse(data["validation-result"]);
  }

  console.log(JSON.stringify(data, null, 2));
}

async function main() {
  // These two files must exist in the CWD
  await validate("cfdv40-ejemplo-signed-tfd.xml", "pac.cer");
}

main();