import { Reporter } from "../reporter/reporter.js";
import { Collector } from "../collector/index.js";
import Inspector from "../inspector/inspector.js";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export async function runCollection(args, browser_options, logger) {
    let collectionArgs = sanitizeInputAndConstructCollectionArgs(args, browser_options);
    const collector = new Collector(collectionArgs, logger);
    const collectionResult = await collector.run();
    const inspector = new Inspector(collectionResult.pageSession, collectionResult.output);
    return inspector.run();
}
/*
 * Generates the report for the specified template and output as HTML and PDF.
 * The PDF is encoded as Base64.
 */
export async function generateHtmlAndPdf(logger, inspectionOutput, templatePath, additionalInspectionOutput) {
    let reporterArgs = {
        printHtmlToConsole: false,
        pdf: true,
        printJsonToConsole: false,
        outputPath: undefined,
        usePandoc: false,
        printYamlToConsole: false,
        extraFiles: additionalInspectionOutput ?? [],
    };
    const reporter = new Reporter(reporterArgs, logger);
    let html = reporter.generateHtmlReport(inspectionOutput, "inspection.html", templatePath);
    let pdfBuffer = await reporter.convertHtmlToPdfInMemory(html);
    return {
        html: html,
        pdf: Buffer.from(pdfBuffer.buffer).toString("base64"),
    };
}
/*
 * The function returns the resolved paths for the available templates.
 * This is necessary to enable other libraries to use the templates contained in the WEC as there paths have to be resolved.
 */
export function availableTemplates() {
    const dntComparisonTemplate = path.join(__dirname, "../assets/template-dnt-comparison.pug");
    const regularTemplate = path.join(__dirname, "../assets/template.pug");
    return {
        dntTemplate: dntComparisonTemplate,
        regularTemplate: regularTemplate,
    };
}
/**
 * Constructs a JSON object containing all Arguments as it is expected by the underlying implementation.
 */
function sanitizeInputAndConstructCollectionArgs(args, browser_options) {
    let sleepOption = isEmptyNumber(args.post_page_load_delay_milliseconds)
        ? 3000
        : args.post_page_load_delay_milliseconds;
    let pageTimeout = isEmptyNumber(args.timeout_milliseconds)
        ? 0
        : args.timeout_milliseconds;
    let maxLinks = isEmptyNumber(args.max_additional_links)
        ? 0
        : args.max_additional_links;
    // Links and URIs can be null when send by the backend. Therefore, we filter.
    let browseLinks = args.links_to_include.filter((value) => value != null);
    let firstPartyUris = args.first_party_uris.filter((value) => value != null);
    // Check that Links are URLs and FirstPartyUris only consist of domains.
    let areAllExtraLinksUrls = browseLinks.every((link) => URL.canParse(link));
    let areAllFirstPartyUrisUrls = firstPartyUris.every((link) => URL.canParse(link));
    if (!areAllFirstPartyUrisUrls) {
        throw new Error("Not all firstPartyURIs are valid.");
    }
    if (!areAllExtraLinksUrls) {
        throw new Error("Not all extra links are invalid.");
    }
    let sanitizedCookies = args.cookies
        .filter((cookie) => cookie.value != null && cookie.key != null)
        .filter((cookie) => !cookie.value.includes(";") &&
        !cookie.value.includes(",") &&
        !cookie.value.includes(" "))
        .filter((cookie) => !cookie.key.includes(";") &&
        !cookie.key.includes(",") &&
        !cookie.key.includes(" "));
    /*
    [set-cookies.ts] expects a string of cookies in the form of
      key1=value1;key2=value2;
    */
    let cookieString = sanitizedCookies.length >= 1
        ? sanitizedCookies
            .map((cookie) => `${cookie.key}=${cookie.value}`)
            .join(";")
        : "";
    return {
        _: [args.website_url],
        url: args.website_url,
        max: maxLinks,
        browseLink: browseLinks,
        sleep: sleepOption,
        firstPartyUri: firstPartyUris,
        pageTimeout: pageTimeout,
        testssl: args.run_testSSL,
        seed: args.link_selection_seed,
        setCookie: cookieString,
        headless: true,
        screenshots: true,
        dnt: args.use_DNT,
        dntJs: false,
        output: undefined,
        overwrite: false,
        yaml: false,
        json: false,
        html: true,
        usePandoc: false,
        pdf: true,
        taskDescription: null,
        quiet: false,
        browserOptions: browser_options,
        lang: "en",
        $0: "website-evidence-collector",
    };
}
function isEmptyNumber(input) {
    return input === null || input === undefined || isNaN(input) || input === 0;
}
