/**
 * @file Produces an html output documenting evidence from websites on processed data in transit and at rest.
 * @author Robert Riemann <robert.riemann@edps.europa.eu>
 * @copyright European Data Protection Supervisor (2019)
 * @license EUPL-1.2
 *
 * @example while inotifywait -e modify assets/template.pug; do ./create-html.js output/inspection.json > output/inspection.html; done
 */
import yaml from "js-yaml";
import fs from "fs";
import path from "path";
import { all as unsafe } from "js-yaml-js-types-esm";
import { Reporter } from "../reporter/reporter.js";
import { create } from "../lib/logger.js";
yaml.DEFAULT_SCHEMA = yaml.DEFAULT_SCHEMA.extend(unsafe);
export default {
    command: "report",
    desc: "Generate reports from collected data",
    builder: (yargs) => {
        return yargs
            .usage("Usage: $0 [options] <JSON file>")
            .example([["$0 /home/user/inspection.json"]])
            .describe("html-template", "Custom pug template to generate HTML output")
            .nargs("html-template", 1)
            .alias("html-template", "t")
            .string("html-template")
            .describe("office-template", "Custom pug template to generate DOCX with NPM html-to-docx or DOCX/ODT with pandoc")
            .nargs("office-template", 1)
            .string("office-template")
            .describe("use-pandoc", "Conversion to DOCX/ODT with pandoc instead of NPM")
            .boolean("use-pandoc")
            .default("use-pandoc", false)
            .describe("extra-file", "Loads other JSON/YAML files in the template array 'extra'")
            .nargs("extra-file", 1)
            .alias("extra-file", "e")
            .array("extra-file")
            .coerce("extra-file", (files) => {
            return files.map((file) => {
                if (file.toLowerCase().endsWith(".yaml") ||
                    file.toLowerCase().endsWith(".yml")) {
                    return yaml.load(fs.readFileSync(file, "utf8"));
                }
                else {
                    return JSON.parse(fs.readFileSync(file, "utf8"));
                }
            });
        })
            .describe("output-file", "Write HTML/PDF/DOCX/ODT output to file according to file extension")
            .nargs("output-file", 1)
            .alias("output-file", "o")
            .string("output-file")
            .check((argv) => {
            if (!argv._[1]) {
                return "Error: You must provide a file name or path";
            }
            return true;
        });
    },
    handler: async (argv) => {
        const runReporterArgs = {
            inspectionJsonPath: argv._[1],
            htmlTemplate: argv.htmlTemplate,
            officeTemplate: argv.officeTemplate,
            usePandoc: argv.usePandoc,
            extraFiles: argv.extraFile || [],
            outputFile: argv.outputFile,
        };
        await runReporter(runReporterArgs);
    },
};
async function runReporter(args) {
    const logger = create({});
    const collectionData = JSON.parse(fs.readFileSync(args.inspectionJsonPath, "utf8"));
    const reporter = new Reporter({
        htmlTemplate: args.htmlTemplate,
        officeTemplate: args.officeTemplate,
        usePandoc: args.usePandoc || false,
        extraFiles: args.extraFiles,
        printHtmlToConsole: !args.outputFile,
        printJsonToConsole: false,
        pdf: false,
        printYamlToConsole: false,
        outputPath: ".",
    }, logger);
    const fileExtension = path.extname(args.outputFile).toLowerCase();
    const outputDir = path.dirname(args.outputFile);
    // Create the output directory if it doesn't exist
    if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, { recursive: true });
    }
    switch (fileExtension) {
        case ".pdf":
            const htmlContent = reporter.generateHtmlReport(collectionData);
            const pdfBuffer = await reporter.convertHtmlToPdfInMemory(htmlContent);
            reporter.saveFile(args.outputFile, pdfBuffer);
            break;
        case ".docx":
        case ".odt":
            await reporter.saveAsOfficeDoc(collectionData, args.outputFile);
            break;
        case ".html":
            reporter.generateHtmlReport(collectionData, args.outputFile);
            break;
        default:
            logger.warn(`File extension ${fileExtension} is not supported.`);
            break;
    }
}
