<html>
<head>
<script>
var gaia = gaia || {};
gaia.chromeOSLogin = {};

gaia.chromeOSLogin.parent_webview_signin_url_ = 'chrome://chrome-signin';
gaia.chromeOSLogin.parent_webview_oob_url_ = 'chrome://oobe';
gaia.chromeOSLogin.parent_webview_ = undefined;
gaia.chromeOSLogin.parent_webview_url_ = undefined;
gaia.chromeOSLogin.initialized_ = false;


function goFirstPage() {
console.error('On first page');
  document.getElementById('page1').hidden = false;
  document.getElementById('page2').hidden = true;
  history.replaceState({}, '', window.location.pathname + '#identifier');
  gaia.chromeOSLogin.backButton(false);
}

gaia.chromeOSLogin.registerHtml5Listener = function() {
  var onMessage = function(e) {
    if (e.origin == gaia.chromeOSLogin.parent_webview_signin_url_ ||
        e.origin == gaia.chromeOSLogin.parent_webview_oob_url_) {
        gaia.chromeOSLogin.parent_webview_ = e.source;
        gaia.chromeOSLogin.parent_webview_url_ = e.origin;
        if (!gaia.chromeOSLogin.initialized_) {
          gaia.chromeOSLogin.initialized_ = true;
          goFirstPage();
        }
    }
  };
  window.addEventListener('message', onMessage);
  window.addEventListener("popstate", function(e) { goBack(); });
  window.postMessage({
      type: 'gaia_saml_api',
      call: {method: 'initialize', requestedVersion: 1}}, '/');
}

gaia.chromeOSLogin.attemptLogin = function(email, password) {
  var msg = {
    'method': 'attemptLogin',
    'email': email,
  };
  gaia.chromeOSLogin.parent_webview_.postMessage(msg,
      gaia.chromeOSLogin.parent_webview_url_);

  // SAML credential passing api for password.
  window.postMessage(
      {type: 'gaia_saml_api',
       call: {method: 'add',
              token: 'token',
              user: email,
              passwordBytes: password,
              keyType: 'KEY_TYPE_PASSWORD_PLAIN'}
      }, '/');
  var services = document.getElementById("services").value;
  if (services) {
    services = JSON.parse(services);
    if (!services)
      services = "Failed to parse test services JSON.";
  } else if (email.endsWith('@corp.example.com') ||
             email.endsWith('@example.test')) {
    // SAML tests.
    services = [];
  } else {
    services = "Services are not set for testing.";
  }

  msg = {
    'method': 'userInfo',
    'services': services,
  };
  gaia.chromeOSLogin.parent_webview_.postMessage(msg,
      gaia.chromeOSLogin.parent_webview_url_);
};

gaia.chromeOSLogin.backButton = function(show) {
  var msg = {
    'method': 'backButton',
    'show': show,
  };
  gaia.chromeOSLogin.parent_webview_.postMessage(msg,
      gaia.chromeOSLogin.parent_webview_url_);
};


function goBack() {
  if (!document.getElementById('page2').hidden) {
    goFirstPage();
  }
}

function goNext() {
  if (!document.getElementById("page1").hidden) {
    document.getElementById("page1").hidden = true;
    document.getElementById("page2").hidden = false;
    history.pushState({}, "", window.location.pathname + "#challengepassword");

    request = new XMLHttpRequest();
    request.open('POST', '/_/embedded/lookup/accountlookup', true);
    request.onreadystatechange = function() {
      if (request.readyState == 4 && request.status == 200) {
        if (request.getResponseHeader("continue"))
          location.assign(request.getResponseHeader("continue"));
      }
    };
    var email = document.getElementById("identifier").value;
    request.send('identifier=' + encodeURIComponent(email));

    gaia.chromeOSLogin.attemptLogin(email, "");
    gaia.chromeOSLogin.backButton(true);
  } else if (!document.getElementById("page2").hidden) {
    var email = document.getElementById("identifier").value;
    var password = document.getElementById("password").value;

    request = new XMLHttpRequest();
    request.open('POST', '/_/embedded/signin/challenge', true);
    request.onreadystatechange = function() {
      if (request.readyState == 4 && request.status == 200) {
        history.pushState({}, "", window.location.pathname + "#close");
      }
    };
    request.send('identifier=' + encodeURIComponent(email));

    gaia.chromeOSLogin.attemptLogin(email, password);
  }
}

function onLoad() {
  gaia.chromeOSLogin.registerHtml5Listener();
}

</script>
</head>
<body onload='onLoad();'>
  Local Auth Server:<br>
  <div id="page1" hidden>
    Email
    <input id="identifier" name="identifier" type="email" spellcheck="false" autocomplete="off" formnovalidate="">
  </div>
  <div id="page2" hidden>
    Password
    <input id="password" name="password" type="password" spellcheck="false" autocomplete="off" formnovalidate="">
    <input id="services" name="services" type="text" spellcheck="false" autocomplete="off" formnovalidate="">
  </div><br>
  <div id='nextButton' onclick='goNext();'>Next</div>
</body>
</html>
