// ============================================================
// Lightweight magic-byte sniffer — verifies the claimed MIME
// against the file's actual header. Covers the types the app
// currently accepts: PDF, PNG, JPEG, GIF, WEBP, DOCX/ODT (zip),
// plain text / CSV / MD (heuristic).
// ============================================================

function sniff(buffer) {
  if (!Buffer.isBuffer(buffer) || buffer.length < 4) return 'application/octet-stream';

  // PDF
  if (buffer.slice(0, 4).toString('ascii') === '%PDF') return 'application/pdf';
  // PNG
  if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) return 'image/png';
  // JPEG
  if (buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff) return 'image/jpeg';
  // GIF
  if (buffer.slice(0, 3).toString('ascii') === 'GIF') return 'image/gif';
  // WEBP: "RIFF" .... "WEBP"
  if (buffer.length >= 12 && buffer.slice(0, 4).toString('ascii') === 'RIFF' && buffer.slice(8, 12).toString('ascii') === 'WEBP') return 'image/webp';
  // ZIP-based (docx, xlsx, pptx, odt)
  if (buffer[0] === 0x50 && buffer[1] === 0x4b && (buffer[2] === 0x03 || buffer[2] === 0x05 || buffer[2] === 0x07)) return 'application/zip';
  // Office legacy (.doc, .xls, .ppt)
  if (buffer[0] === 0xd0 && buffer[1] === 0xcf && buffer[2] === 0x11 && buffer[3] === 0xe0) return 'application/x-cfb';

  // Heuristic: printable ASCII / UTF-8 → text
  var printable = 0;
  var sample = buffer.slice(0, Math.min(512, buffer.length));
  for (var i = 0; i < sample.length; i++) {
    var b = sample[i];
    if (b === 9 || b === 10 || b === 13 || (b >= 32 && b < 127) || b >= 128) printable++;
  }
  if (printable / sample.length > 0.95) return 'text/plain';

  return 'application/octet-stream';
}

// Check that the claimed MIME type is compatible with the sniffed type.
function matches(claimedMime, buffer) {
  var actual = sniff(buffer);
  if (!claimedMime) return false;
  if (claimedMime === actual) return true;
  // Word docx files claim application/vnd.openxmlformats-... but sniff as zip
  if (actual === 'application/zip' && (
    claimedMime === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
    claimedMime === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
    claimedMime === 'application/vnd.openxmlformats-officedocument.presentationml.presentation' ||
    claimedMime === 'application/vnd.oasis.opendocument.text'
  )) return true;
  // Older .doc/.xls
  if (actual === 'application/x-cfb' && /msword|excel|ms-office|ms-powerpoint/.test(claimedMime)) return true;
  // text variants
  if (actual === 'text/plain' && (claimedMime === 'text/csv' || claimedMime === 'text/markdown' || claimedMime === 'application/json' || claimedMime === 'text/plain')) return true;
  return false;
}

module.exports = { sniff: sniff, matches: matches };
