import { countWords, readPdfText, withPdfDocument } from '../utils.js';
import { asOptionalString, formatDateLike } from '../inspect/shared.js';
/**
 * A PDF is encrypted when its trailer references an encryption dictionary as an
 * indirect object (e.g. `/Encrypt 12 0 R`). AcroForm presence is unrelated to
 * encryption and must not drive this flag.
 */
export function isPdfEncrypted(buffer, info) {
    if (info.Encrypted === true)
        return true;
    return /\/Encrypt\s+\d+\s+\d+\s+R\b/.test(buffer.toString('latin1'));
}
function parsePdfDate(value) {
    if (!value)
        return undefined;
    const str = String(value);
    // PDF dates: D:YYYYMMDDHHmmSS or plain ISO strings
    const match = str.match(/^D:(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/);
    if (match) {
        return `${match[1]}-${match[2]}-${match[3]}T${match[4]}:${match[5]}:${match[6]}Z`;
    }
    return formatDateLike(str);
}
export async function inspectPdf(filePath, buffer, sampleParagraphs) {
    // One open document answers both questions; the properties and the body come
    // from the same parse rather than from two.
    const data = await withPdfDocument(buffer, async (document) => {
        // Sequential, not concurrent: both calls go over one pdf.js message port,
        // and issuing them together corrupts it (`DataCloneError` from the worker
        // loopback). One open document, two questions, asked in turn.
        const text = await readPdfText(document);
        const meta = await document.getInfo();
        return { text: text.text, pages: text.total, info: (meta.info ?? {}) };
    });
    const info = data.info;
    const properties = {
        title: asOptionalString(info.Title),
        subject: asOptionalString(info.Subject),
        author: asOptionalString(info.Author),
        keywords: asOptionalString(info.Keywords),
        createdDate: parsePdfDate(info.CreationDate),
        modifiedDate: parsePdfDate(info.ModDate),
    };
    // PDFs have limited risk flag detection
    const riskFlags = {
        comments: false,
        trackedChanges: false,
        hyperlinks: false,
        embeddedObjects: false,
        footnotes: false,
        endnotes: false,
        macros: false,
        headerFooter: false,
        tables: false,
        encrypted: isPdfEncrypted(buffer, info),
    };
    const text = data.text || '';
    const words = countWords(text);
    const paragraphs = text.split(/\n\n+/).filter(p => p.trim().length > 0).length;
    const contentStats = {
        words,
        pages: data.pages,
        pagesEstimated: false,
        paragraphs,
        characters: text.length,
        tables: 0,
        images: 0,
    };
    // Build preview from text
    const textParagraphs = text.split(/\n\n+/).filter(p => p.trim().length > 0);
    const previewParagraphs = [];
    const limit = Math.min(sampleParagraphs, textParagraphs.length);
    for (let i = 0; i < limit; i++) {
        previewParagraphs.push({
            index: i,
            text: textParagraphs[i].trim().replace(/\s+/g, ' '),
            isHeading: false,
        });
    }
    const preview = {
        truncated: textParagraphs.length > sampleParagraphs,
        paragraphs: previewParagraphs,
    };
    return { properties, riskFlags, contentStats, preview };
}
//# sourceMappingURL=inspect-pdf.js.map