/**
 * This test checks to see if the smtp password failure is handled correctly
 * when the server drops the connection on an authentication error.
 * The steps are:
 *   - Have an invalid password in the password database.
 *   - Re-initiate connection, this time select enter new password, check that
 *     we get a new password prompt and can enter the password.
 *
 */

var { MailServices } = ChromeUtils.importESModule(
  "resource:///modules/MailServices.sys.mjs"
);

/* import-globals-from ../../../test/resources/alertTestUtils.js */
/* import-globals-from ../../../test/resources/passwordStorage.js */
load("../../../resources/alertTestUtils.js");
load("../../../resources/passwordStorage.js");

var server;
var attempt = 0;

var kIdentityMail = "identity@foo.invalid";
var kSender = "from@foo.invalid";
var kTo = "to@foo.invalid";
var kUsername = "testsmtp";
// Password needs to match the login information stored in the signons json
// file.
var kValidPassword = "smtptest1";

function confirmExPS() {
  switch (++attempt) {
    // First attempt, retry.
    case 1:
      dump("\nAttempting Retry\n");
      return 0;
    // Second attempt, enter a new password.
    case 2:
      dump("\nEnter new password\n");
      return 2;
    default:
      do_throw("unexpected attempt number " + attempt);
      return 1;
  }
}

function promptPasswordPS(
  aParent,
  aDialogTitle,
  aText,
  aPassword,
  aCheckMsg,
  aCheckState
) {
  if (attempt == 2) {
    aPassword.value = kValidPassword;
    aCheckState.value = true;
    return true;
  }
  return false;
}

add_task(async function () {
  function createHandler(d) {
    var handler = new SMTP_RFC2821_handler(d);
    handler.dropOnAuthFailure = true;
    // Username needs to match the login information stored in the signons json
    // file.
    handler.kUsername = kUsername;
    handler.kPassword = kValidPassword;
    handler.kAuthRequired = true;
    handler.kAuthSchemes = ["PLAIN", "LOGIN"]; // make match expected transaction below
    return handler;
  }
  server = setupServerDaemon(createHandler);

  // Prepare files for passwords (generated by a script in bug 1018624).
  await setupForPassword("signons-mailnews1.8.json");

  registerAlertTestUtils();

  // Test file
  var testFile = do_get_file("data/message1.eml");

  // Ensure we have at least one mail account
  localAccountUtils.loadLocalMailAccount();

  // Start the fake SMTP server. The server's socket type defaults to
  // Ci.nsMsgSocketType.plain, so no need to set it.
  server.start();
  var smtpServer = getBasicSmtpServer(server.port);
  var identity = getSmtpIdentity(kIdentityMail, smtpServer);

  // This time with auth
  test = "Auth sendMailMessage";

  smtpServer.authMethod = Ci.nsMsgAuthMethod.passwordCleartext;
  smtpServer.username = kUsername;

  do_test_pending();

  const messageId = Cc["@mozilla.org/messengercompose/computils;1"]
    .createInstance(Ci.nsIMsgCompUtils)
    .msgGenerateMessageId(identity, null);

  smtpServer.sendMailMessage(
    testFile,
    MailServices.headerParser.parseEncodedHeaderW(kTo),
    [],
    identity,
    kSender,
    null,
    null,
    false,
    messageId,
    RequestObserver
  );

  server.performTest();
});

var RequestObserver = {
  onStartRequest() {},
  onStopRequest(request, rc) {
    // Check for ok status.
    Assert.equal(rc, 0);
    // Now check the new password has been saved.
    const logins = Services.logins.findLogins(
      "smtp://localhost",
      null,
      "smtp://localhost"
    );

    Assert.equal(logins.length, 1);
    Assert.equal(logins[0].username, kUsername);
    Assert.equal(logins[0].password, kValidPassword);

    server.stop();

    var thread = Services.tm.currentThread;
    while (thread.hasPendingEvents()) {
      thread.processNextEvent(true);
    }

    do_test_finished();
  },
};
