/*
 * General testing of the JS Mime Emitter to make sure it doesn't choke on any
 *  scenarios.
 *
 * We test:
 * - Straight text/plain with and without attachment.
 * - Straight text/html with and without attachment.
 *   (This should cover RSS feeds too...)
 * - multipart/alternative containing text/plain and text/html, w/w/o attachment
 * -
 */

do_import_script("../mailnews/db/gloda/test/resources/messageGenerator.js");
do_import_script("../mailnews/db/gloda/test/resources/glodaTestHelper.js");

Components.utils.import("resource://app/modules/gloda/mimemsg.js");

// Create a message generator
var msgGen = new MessageGenerator();

var partText = new SyntheticPartLeaf("I am text! Woo!");
var partHtml = new SyntheticPartLeaf(
  "<html><head></head><body>I am HTML! Woo! </body></html>",
  {
    contentType: "text/html"
  }
);
var partAlternative = new SyntheticPartMultiAlternative([partText, partHtml]);
var partMailingListFooter = new SyntheticPartLeaf("I am an annoying footer!");

var tachText = {filename: 'bob.txt', body: 'I like cheese!'};
var partTachText = new SyntheticPartLeaf(tachText.body, tachText);

var tachImage = {filename: 'bob.png', contentType: 'image/png',
                 encoding: 'base64', charset: null, format: null,
                 body: 'YWJj\n'};
var partTachImage = new SyntheticPartLeaf(tachImage.body, tachImage);

var relImage = {contentType: 'image/png',
                encoding: 'base64', charset: null, format: null,
                contentId: 'part1.foo@bar.com',
                body: 'YWJj\n'};
var partRelImage = new SyntheticPartLeaf(relImage.body, relImage);

var tachApplication = {filename: 'funky.funk',
                       contentType: 'application/x-funky', body: 'funk!'};
var partTachApplication = new SyntheticPartLeaf(tachApplication.body,
                                                tachApplication);

var partTachMessage = new SyntheticPartMessage(msgGen.makeMessage());

var messageInfos = [
  // -- simple
  {
    name: 'text/plain',
    bodyPart: partText,
  },
  {
    name: 'text/html',
    bodyPart: partHtml,
  },
  // -- simple w/attachment
  {
    name: 'text/plain w/text attachment (=> multipart/mixed)',
    bodyPart: partText,
    attachments: [tachText],
  },
  {
    name: 'text/plain w/image attachment (=> multipart/mixed)',
    bodyPart: partText,
    attachments: [tachImage],
  },
  {
    name: 'text/plain w/app attachment (=> multipart/mixed)',
    bodyPart: partText,
    attachments: [tachApplication],
  },
  {
    name: 'text/html w/text attachment (=> multipart/mixed)',
    bodyPart: partHtml,
    attachments: [tachText],
  },
  {
    name: 'text/html w/image attachment (=> multipart/mixed)',
    bodyPart: partHtml,
    attachments: [tachImage],
  },
  {
    name: 'text/html w/app attachment (=> multipart/mixed)',
    bodyPart: partHtml,
    attachments: [tachApplication],
  },
  // -- alternatives
  {
    name: 'multipart/alternative: text/plain, text/html',
    bodyPart: partAlternative,
  },
  {
    name: 'multipart/alternative plain/html w/text attachment',
    bodyPart: partAlternative,
    attachments: [tachText],
  },
  {
    name: 'multipart/alternative plain/html w/image attachment',
    bodyPart: partAlternative,
    attachments: [tachImage],
  },
  {
    name: 'multipart/alternative plain/html w/app attachment',
    bodyPart: partAlternative,
    attachments: [tachApplication],
  },
  // -- S/MIME.
  {
    name: 'S/MIME alternative',
    bodyPart: new SyntheticPartMultiSigned(partAlternative),
  },
  {
    name: 'S/MIME alternative with text attachment inside',
    // we have to do the attachment packing ourselves on this one.
    bodyPart: new SyntheticPartMultiSigned(
      new SyntheticPartMultiMixed([partAlternative, partTachText])),
  },
  {
    name: 'S/MIME alternative with image attachment inside',
    // we have to do the attachment packing ourselves on this one.
    bodyPart: new SyntheticPartMultiSigned(
      new SyntheticPartMultiMixed([partAlternative, partTachImage])),
  },
  {
    name: 'S/MIME alternative with app attachment inside',
    // we have to do the attachment packing ourselves on this one.
    bodyPart: new SyntheticPartMultiSigned(
      new SyntheticPartMultiMixed([partAlternative, partTachApplication])),
  },
  {
    name: 'S/MIME alternative wrapped in mailing list',
    bodyPart: new SyntheticPartMultiMixed(
      [new SyntheticPartMultiSigned(partAlternative), partMailingListFooter]),
  },
  // -- attached RFC822
  {
    // not your average attachment, pack ourselves for now
    name: 'attached rfc822',
    bodyPart: new SyntheticPartMultiMixed([partAlternative, partTachMessage]),
  },
  // -- multipart/related
  {
    name: 'multipart/related',
    bodyPart: new SyntheticPartMultiRelated([partHtml, partRelImage]),
  },
  {
    name: 'multipart/related inside multipart/alternative',
    bodyPart: new SyntheticPartMultiAlternative([partText,
      new SyntheticPartMultiRelated([partHtml, partRelImage])]),
  },
];

function setup_create_message(info) {
  info._synMsg = msgGen.makeMessage(info);
  next_test();
}

var emittyFolder;

/**
 * Actually inject all the messages we created above.
 */
function setup_inject_messages() {
  let synMessages = [info._synMsg for each
                      ([, info] in Iterator(messageInfos))];
  writeMessagesToMbox(synMessages, gProfileDir,
                      "Mail", "Local Folders", "emitty");
  emittyFolder = gLocalIncomingServer.rootMsgFolder.addSubfolder("emitty");
  updateFolderAndNotify(emittyFolder, next_test);
}

function test_stream_message(info) {
  let msgHdr =
    emittyFolder.msgDatabase.getMsgHdrForMessageID(info._synMsg.messageId);

  MsgHdrToMimeMessage(msgHdr, null, function(aMsgHdr, aMimeMsg) {
    verify_stream_message(info, info._synMsg, aMsgHdr, aMimeMsg);
  });
}

/**
 * Verify the streamed results are what we wanted.  For now, this just means
 *  receiving a representation; we don't check it for correctness.
 */
function verify_stream_message(aInfo, aSynMsg, aMsgHdr, aMimeMsg) {
  if (!aMimeMsg)
    do_throw("We really should have gotten a result!");
  next_test();
}

/* ===== Driver ===== */

var tests = [
  parameterizeTest(setup_create_message, messageInfos),
  setup_inject_messages,
  parameterizeTest(test_stream_message, messageInfos),
];

function run_test() {
  // use mbox injection because the fake server chokes sometimes right now
  injectMessagesUsing(INJECT_MBOX);
  glodaHelperRunTests(tests);
}

