#!/usr/bin/env node
// Patches imapflow to handle Poste.io servers returning IMAP NO/BAD/BYE
// responses where some TEXT attributes have undefined .value, causing
// `val.value.trim()` to throw "Cannot read properties of undefined".
const fs = require('fs');
const path = require('path');

const file = path.join(__dirname, '../node_modules/imapflow/lib/imap-flow.js');
let src = fs.readFileSync(file, 'utf8');

const patches = [
  {
    bad: `.map(val => val.value.trim())`,
    fixed: `.map(val => (val.value != null ? val.value.trim() : ''))`,
  },
  {
    bad: `section[0].value.toUpperCase().trim()`,
    fixed: `(section[0].value || '').toUpperCase().trim()`,
  },
  {
    bad: `attr.value.toUpperCase().trim()`,
    fixed: `(attr.value || '').toUpperCase().trim()`,
  },
  {
    bad: `val.value.toUpperCase().trim()`,
    fixed: `(val.value || '').toUpperCase().trim()`,
  },
  {
    bad: `contentType.value.toLowerCase().trim()`,
    fixed: `(contentType.value || '').toLowerCase().trim()`,
  },
  {
    bad: `disposition.value.toLowerCase().trim()`,
    fixed: `(disposition.value || '').toLowerCase().trim()`,
  },
];

let total = 0;
for (const p of patches) {
  const re = new RegExp(p.bad.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g');
  const count = (src.match(re) || []).length;
  if (count > 0) {
    src = src.replaceAll(p.bad, p.fixed);
    total += count;
    console.log(`[patch-imapflow] patched ${count} occurrence(s) of: ${p.bad}`);
  }
}

if (total > 0) {
  fs.writeFileSync(file, src, 'utf8');
  console.log(`[patch-imapflow] total patched ${total} occurrence(s) in imap-flow.js`);
} else {
  console.log('[patch-imapflow] already patched or patterns not found — no changes made');
}

// Also patch parser-instance.js (this.remainder can be undefined on malformed Poste.io responses)
const parserFile = path.join(__dirname, '../node_modules/imapflow/lib/handler/parser-instance.js');
if (fs.existsSync(parserFile)) {
  let parserSrc = fs.readFileSync(parserFile, 'utf8');
  let parserPatched = 0;
  const parserPatches = [
    { bad: `this.humanReadable = this.remainder.trim();`, fixed: `this.humanReadable = (this.remainder || '').trim();` },
    { bad: `this.humanReadable = this.remainder.substring(i + 1).trim();`, fixed: `this.humanReadable = (this.remainder || '').substring(i + 1).trim();` },
  ];
  for (const p of parserPatches) {
    if (parserSrc.includes(p.bad)) {
      parserSrc = parserSrc.replaceAll(p.bad, p.fixed);
      parserPatched++;
      console.log(`[patch-imapflow] patched parser-instance.js: ${p.bad}`);
    }
  }
  if (parserPatched > 0) fs.writeFileSync(parserFile, parserSrc, 'utf8');
}

// Also patch nodemailer inside imapflow (malformed Content-Type headers)
const nodemailerFile = path.join(__dirname, '../node_modules/imapflow/node_modules/nodemailer/lib/mime-node/index.js');
if (fs.existsSync(nodemailerFile)) {
  let nodemailerSrc = fs.readFileSync(nodemailerFile, 'utf8');
  const nodemailerBad = `this.contentType = structured.value.trim().toLowerCase();`;
  const nodemailerFixed = `this.contentType = ((structured && structured.value) || '').trim().toLowerCase();`;
  if (nodemailerSrc.includes(nodemailerBad)) {
    nodemailerSrc = nodemailerSrc.replaceAll(nodemailerBad, nodemailerFixed);
    fs.writeFileSync(nodemailerFile, nodemailerSrc, 'utf8');
    console.log('[patch-imapflow] patched nodemailer mime-node/index.js');
  }
}
