/*
 * Copyright 2015 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */


void function() {

  /**
   * Asserts that the displayed dialog is in the center of the screen.
   *
   * @param {HTMLDialogElement?} opt_dialog to check, or test default
   */
  function checkDialogCenter(opt_dialog) {
    var d = opt_dialog || dialog;
    var expectedTop = (window.innerHeight - d.offsetHeight) / 2;
    var expectedLeft = (window.innerWidth - d.offsetWidth) / 2;
    var rect = d.getBoundingClientRect();
    assert.closeTo(rect.top, expectedTop, 1, 'top should be nearby');
    assert.closeTo(rect.left, expectedLeft, 1, 'left should be nearby');
  }

  /**
   * Creates a fake KeyboardEvent.
   *
   * @param {number} keyCode to press
   * @param {string?} opt_type to use, default keydown
   * @return {!Event} event
   */
  function createKeyboardEvent(keyCode, opt_type) {
    var ev = document.createEvent('Events');
    ev.initEvent(opt_type || 'keydown', true, true);
    ev.keyCode = keyCode;
    ev.which = keyCode;
    return ev;
  }

  /**
   * Cleans up any passed DOM elements.
   *
   * @param {!Element} el to clean up
   * @return {!Element} the same element, for chaining
   */
  var cleanup = (function() {
    var e = [];
    teardown(function() {
      e.forEach(function(el) {
        try {
          el.close();  // try to close dialogs
        } catch (e) {}
        el.parentElement && el.parentElement.removeChild(el);
      });
      e = [];
    });

    return function(el) {
      e.push(el);
      return el;
    };
  })();

  /**
   * Creates a dialog for testing that will be cleaned up later.
   *
   * @param {string?} opt_content to be used as innerHTML
   */
  function createDialog(opt_content) {
    var dialog = document.createElement('dialog');
    dialog.innerHTML = opt_content || 'Dialog #' + (cleanup.length);
    document.body.appendChild(dialog);
    if (window.location.search == '?force') {
      dialogPolyfill.forceRegisterDialog(dialog);
    } else {
      dialogPolyfill.registerDialog(dialog);
    }
    return cleanup(dialog);
  }

  var dialog;  // global dialog for all tests
  setup(function() {
    dialog = createDialog('Default Dialog');
  });

  suite('basic', function() {
    test('show and close', function() {
      assert.isFalse(dialog.hasAttribute('open'));
      dialog.show();
      assert.isTrue(dialog.hasAttribute('open'));
      assert.isTrue(dialog.open);

      var returnValue = 1234;
      dialog.close(returnValue);
      assert.isFalse(dialog.hasAttribute('open'));
      assert.equal(dialog.returnValue, returnValue);

      dialog.show();
      dialog.close();
      assert.isFalse(dialog.open);
      assert.equal(dialog.returnValue, returnValue);
    });
    test('open property', function() {
      assert.isFalse(dialog.hasAttribute('open'));
      dialog.show();
      assert.isTrue(dialog.hasAttribute('open'));
      assert.isTrue(dialog.open);

      dialog.open = false;
      assert.isFalse(dialog.open);
      assert.isFalse(dialog.hasAttribute('open'),
          'open property should clear attribute');
      assert.throws(dialog.close);

      var overlay = document.querySelector('._dialog_overlay');
      assert.isNull(overlay);
    });
    test('show/showModal interaction', function() {
      assert.isFalse(dialog.hasAttribute('open'));
      dialog.show();

      // If the native dialog is being tested, show/showModal are not already
      // bound, so wrap them in helper methods for throws/doesNotThrow.
      var show = function() { dialog.show(); };
      var showModal = function() { dialog.showModal(); };

      assert.doesNotThrow(show);
      assert.throws(showModal);

      dialog.open = false;
      assert.doesNotThrow(showModal);
      assert.doesNotThrow(show);  // show after showModal does nothing
      assert.throws(showModal);
      // TODO: check dialog is still modal

      assert.isTrue(dialog.open);
    });
    test('setAttribute reflects property', function() {
      dialog.setAttribute('open', '');
      assert.isTrue(dialog.open, 'attribute opens dialog');
    });
    test('changing open to dummy value is ignored', function() {
      dialog.showModal();

      dialog.setAttribute('open', 'dummy, ignored');
      assert.isTrue(dialog.open, 'dialog open with dummy open value');

      var overlay = document.querySelector('._dialog_overlay');
      assert(overlay, 'dialog is still modal');
    });
    test('show/showModal outside document', function() {
      dialog.open = false;
      dialog.parentNode.removeChild(dialog);

      assert.throws(function() { dialog.showModal(); });

      assert.doesNotThrow(function() { dialog.show(); });
      assert.isTrue(dialog.open, 'can open non-modal outside document');
      assert.isFalse(document.body.contains(dialog));
    });
    test('has a11y property', function() {
      assert.equal(dialog.getAttribute('role'), 'dialog', 'role should be dialog');
    });
  });

  suite('DOM', function() {
    setup(function(done) {
      // DOM tests wait for modal to settle, so MutationOberver doesn't coalesce attr changes
      dialog.showModal();
      window.setTimeout(done, 0);
    });
    test('DOM direct removal', function(done) {
      assert.isTrue(dialog.open);
      assert.isNotNull(document.querySelector('.backdrop'));

      var parentNode = dialog.parentNode;
      parentNode.removeChild(dialog);

      // DOMNodeRemoved defers its task a frame (since it occurs before removal, not after). This
      // doesn't effect MutationObserver, just delays the test a frame.
      window.setTimeout(function() {
        assert.isNull(document.querySelector('.backdrop'), 'dialog removal should clear modal');

        assert.isTrue(dialog.open, 'removed dialog should still be open');
        parentNode.appendChild(dialog);

        assert.isTrue(dialog.open, 're-added dialog should still be open');
        assert.isNull(document.querySelector('.backdrop'), 're-add dialog should not be modal');

        done();
      }, 0);
    });
    test('DOM removal inside other element', function(done) {
      var div = cleanup(document.createElement('div'));
      document.body.appendChild(div);
      div.appendChild(dialog);

      document.body.removeChild(div);

      window.setTimeout(function() {
        assert.isNull(document.querySelector('.backdrop'), 'dialog removal should clear modal');
        assert.isTrue(dialog.open, 'removed dialog should still be open');
        done();
      }, 0);
    });
    test('DOM instant remove/add', function(done) {
      var div = cleanup(document.createElement('div'));
      document.body.appendChild(div);
      dialog.parentNode.removeChild(dialog);
      div.appendChild(dialog);

      window.setTimeout(function() {
        assert.isNull(document.querySelector('.backdrop'), 'backdrop should disappear');
        assert.isTrue(dialog.open);
        done();
      }, 0);
    });
  });

  suite('position', function() {
    test('non-modal is not centered', function() {
      var el = cleanup(document.createElement('div'));
      dialog.parentNode.insertBefore(el, dialog);
      var testRect = el.getBoundingClientRect();

      dialog.show();
      var rect = dialog.getBoundingClientRect();

      assert.equal(rect.top, testRect.top, 'dialog should not be centered');
    });
    test('default modal centering', function() {
      dialog.showModal();
      checkDialogCenter();
      assert.ok(dialog.style.top, 'expected top to be set');
      dialog.close();
      assert.notOk(dialog.style.top, 'expected top to be cleared');
    });
    test('modal respects static position', function() {
      dialog.style.top = '10px';
      dialog.showModal();

      var rect = dialog.getBoundingClientRect();
      assert.equal(rect.top, 10);
    });
    test('modal recentering', function() {
      var pX = document.body.scrollLeft;
      var pY = document.body.scrollTop;
      var big = cleanup(document.createElement('div'));
      big.style.height = '200vh';  // 2x view height
      document.body.appendChild(big);

      try {
        var scrollValue = 200;  // don't use incredibly large values
        dialog.showModal();
        dialog.close();

        window.scrollTo(0, scrollValue);
        dialog.showModal();
        checkDialogCenter();  // must be centered, even after scroll
        var rectAtScroll = dialog.getBoundingClientRect();

        // after scroll, we aren't recentered, check offset
        window.scrollTo(0, 0);
        var rect = dialog.getBoundingClientRect();
        assert.closeTo(rectAtScroll.top + scrollValue, rect.top, 1);
      } finally {
        window.scrollTo(pX, pY);
      }
    });
    test('clamped to top of page', function() {
      var big = cleanup(document.createElement('div'));
      big.style.height = '200vh';  // 2x view height
      document.body.appendChild(big);
      document.documentElement.scrollTop = document.documentElement.scrollHeight / 2;

      dialog.style.height = document.documentElement.scrollHeight + 200 + 'px';
      dialog.showModal();

      var visibleRect = dialog.getBoundingClientRect();
      assert.equal(visibleRect.top, 0, 'large dialog should be visible at top of page');

      var style = window.getComputedStyle(dialog);
      assert.equal(style.top, document.documentElement.scrollTop + 'px',
          'large dialog should be absolutely positioned at scroll top');
    });
  });

  suite('backdrop', function() {
    test('backdrop div on modal', function() {
      dialog.showModal();
      var foundBackdrop = document.querySelector('.backdrop');
      assert.isNotNull(foundBackdrop);

      var sibling = dialog.nextElementSibling;
      assert.strictEqual(foundBackdrop, sibling);
    });
    test('no backdrop on non-modal', function() {
      dialog.show();
      assert.isNull(document.querySelector('.backdrop'));
      dialog.close();
    });
    test('backdrop click appears as dialog', function() {
      dialog.showModal();
      var backdrop = dialog.nextElementSibling;

      var clickFired = 0;
      var helper = function(ev) {
        assert.equal(ev.target, dialog);
        ++clickFired;
      };

      dialog.addEventListener('click', helper)
      backdrop.click();
      assert.equal(clickFired, 1);
    });
    test('backdrop click focuses dialog', function() {
      dialog.showModal();
      dialog.tabIndex = 0;

      var input = document.createElement('input');
      input.type = 'text';
      dialog.appendChild(input);

      // TODO: It would be nice to check `input` instead here, but there's no more reliable ways
      // to emulate a browser tab event (Firefox, Chrome etc have made it a security violation).

      var backdrop = dialog.nextElementSibling;
      backdrop.click();
      assert.equal(document.activeElement, dialog);
    });
  });

  suite('form focus', function() {
    test('non-modal inside modal is focusable', function() {
      var sub = createDialog();
      dialog.appendChild(sub);

      var input = document.createElement('input');
      input.type = 'text';
      sub.appendChild(input);

      dialog.showModal();
      sub.show();

      input.focus();
      assert.equal(input, document.activeElement);
    });
    test('clear focus when nothing focusable in modal', function() {
      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      document.body.appendChild(input);
      input.focus();

      var previous = document.activeElement;
      dialog.showModal();
      assert.notEqual(previous, document.activeElement);
    });
    test('default focus on modal', function() {
      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      dialog.appendChild(input);

      var anotherInput = cleanup(document.createElement('input'));
      anotherInput.type = 'text';
      dialog.appendChild(anotherInput);

      dialog.showModal();
      assert.equal(document.activeElement, input);
    });
    test('default focus on non-modal', function() {
      var div = cleanup(document.createElement('div'));
      div.tabIndex = 4;
      dialog.appendChild(div);

      dialog.show();
      assert.equal(document.activeElement, div);
    });
    test('autofocus element chosen', function() {
      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      dialog.appendChild(input);

      var inputAF = cleanup(document.createElement('input'));
      inputAF.type = 'text';
      inputAF.autofocus = true;
      dialog.appendChild(inputAF);

      dialog.showModal();
      assert.equal(document.activeElement, inputAF);
    });
    test('child modal dialog', function() {
      dialog.showModal();

      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      dialog.appendChild(input);
      input.focus();
      assert.equal(document.activeElement, input);

      // NOTE: This is a single sub-test, but all the above tests could be run
      // again in a sub-context (i.e., dialog within dialog).
      var child = createDialog();
      child.showModal();
      assert.notEqual(document.activeElement, input,
          'additional modal dialog should clear parent focus');

      child.close();
      assert.notEqual(document.activeElement, input,
          'parent focus should not be restored');
    });
    test('don\'t scroll anything into focus', function() {
      // https://github.com/GoogleChrome/dialog-polyfill/issues/119

      var div = cleanup(document.createElement('div'));
      document.body.appendChild(div);

      var inner = document.createElement('div');
      inner.style.height = '10000px';
      div.appendChild(inner);

      div.appendChild(dialog);

      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      dialog.appendChild(input);

      var prev = document.documentElement.scrollTop;
      dialog.showModal();
      assert.equal(document.documentElement.scrollTop, prev);
    });
  });

  suite('top layer / inert', function() {
    test('background focus allowed on non-modal', function() {
      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      document.body.appendChild(input);
      input.focus();

      dialog.show();
      assert.notEqual(document.activeElement, input,
        'non-modal dialog should clear focus, even with no dialog content');

      document.body.focus();
      input.focus();
      assert.equal(document.activeElement, input,
          'non-modal should allow background focus');
    });
    test('modal disallows background focus', function() {
      var input = cleanup(document.createElement('input'));
      input.type = 'text';
      document.body.appendChild(input);

      dialog.showModal();
      input.focus();

      if (!document.hasFocus()) {
        // Browsers won't trigger a focus event if they're not in the
        // foreground, so we can't intercept it. However, they'll fire one when
        // restored, before a user can get to any incorrectly focused element.
        console.warn('background focus test requires document focus');
        document.documentElement.focus();
      }
      assert.notEqual(document.activeElement, input,
          'modal should disallow background focus');
    });
    test('overlay is a sibling of topmost dialog', function() {
      var stacking = cleanup(document.createElement('div'));
      stacking.style.opacity = 0.8;  // creates stacking context
      document.body.appendChild(stacking);
      stacking.appendChild(dialog);
      dialog.showModal();

      var overlay = document.querySelector('._dialog_overlay');
      assert.isNotNull(overlay);
      assert.equal(overlay.parentNode, dialog.parentNode);
    });
    test('overlay is between topmost and remaining dialogs', function() {
      dialog.showModal();

      var other = cleanup(createDialog());
      document.body.appendChild(other);
      other.showModal();

      var overlay = document.querySelector('._dialog_overlay');
      assert.isNotNull(overlay);
      assert.equal(overlay.parentNode, other.parentNode);

      assert.isAbove(+other.style.zIndex, +overlay.style.zIndex, 'top-most dialog above overlay');
      assert.isAbove(+overlay.style.zIndex, +dialog.style.zIndex, 'overlay above other dialogs');
    });
  });

  suite('events', function() {
    test('close event', function() {
      var closeFired = 0;
      dialog.addEventListener('close', function() {
        ++closeFired;
      });

      dialog.show();
      assert.equal(closeFired, 0);

      dialog.close();
      assert.equal(closeFired, 1);

      assert.throws(dialog.close);  // can't close already closed dialog
      assert.equal(closeFired, 1);

      dialog.showModal();
      dialog.close();
      assert.equal(closeFired, 2);
    });
    test('cancel event', function() {
      dialog.showModal();
      dialog.dispatchEvent(createKeyboardEvent(27));
      assert.isFalse(dialog.open, 'esc should close modal');

      var cancelFired = 0;
      dialog.addEventListener('cancel', function() {
        ++cancelFired;
      });
      dialog.showModal();
      dialog.dispatchEvent(createKeyboardEvent(27));
      assert.equal(cancelFired, 1, 'expected cancel to be fired');
      assert.isFalse(dialog.open), 'esc should close modal again';

      // Sanity-check that non-modals aren't effected.
      dialog.show();
      dialog.dispatchEvent(createKeyboardEvent(27));
      assert.isTrue(dialog.open, 'esc should only close modal dialog');
      assert.equal(cancelFired, 1);
    });
    test('overlay click is prevented', function() {
      dialog.showModal();

      var overlay = document.querySelector('._dialog_overlay');
      assert.isNotNull(overlay);

      var helper = function(ev) {
        throw Error('body should not be clicked');
      };
      try {
        document.body.addEventListener('click', helper);
        overlay.click();
      } finally {
        document.body.removeEventListener('click', helper);
      }
    });
  });

  suite('form', function() {
    test('method attribute is translated to property', function() {
      var form = document.createElement('form');
      form.method = 'dialog';
      assert.equal(form.method, 'dialog');

      form.method = 'PoSt';
      assert.equal(form.method, 'post');
      assert.equal(form.getAttribute('method'), 'PoSt');
    });
    test('dialog method input', function() {
      var value = 'ExpectedValue' + Math.random();

      var form = document.createElement('form');
      try {
        form.method = 'dialog';
      } catch (e) {
        // Setting the method directly throws an exception in <=IE9.
        form.setAttribute('method', 'dialog');
      }
      dialog.appendChild(form);

      var input = document.createElement('input');
      input.type = 'submit';
      input.value = value;
      form.appendChild(input);

      var closeCount = 0;
      dialog.addEventListener('close', function() {
        ++closeCount;
      });

      dialog.show();
      input.focus();  // emulate user focus action
      input.click();

      assert.isFalse(dialog.open);
      assert.equal(dialog.returnValue, value);
      assert.equal(closeCount, 1);
    });
    test('dialog with button preventDefault does not trigger submit', function() {
      var form = document.createElement('form');
      form.setAttribute('method', 'dialog');
      dialog.appendChild(form);

      var button = document.createElement('button');
      button.value = 'does not matter';
      form.appendChild(button);
      button.addEventListener('click', function(ev) {
        ev.preventDefault();
      });

      dialog.showModal();
      button.click();

      assert.isTrue(dialog.open, 'dialog should remain open');
      assert.equal(dialog.returnValue, '');
    });
    test('dialog programmatic submit does not change returnValue', function() {
      var form = document.createElement('form');
      form.setAttribute('method', 'dialog');

      dialog.returnValue = 'manually set';  // set before appending
      dialog.appendChild(form);

      dialog.showModal();
      form.submit();
      assert.isFalse(dialog.open);

      assert.equal(dialog.returnValue, 'manually set', 'returnValue should not change');
    });
    test('dialog method button', function() {
      var value = 'ExpectedValue' + Math.random();

      var form = document.createElement('form');
      form.setAttribute('method', 'dialog');
      dialog.appendChild(form);

      var button = document.createElement('button');
      button.value = value;
      form.appendChild(button);

      dialog.showModal();
      button.focus();  // emulate user focus action
      button.click();

      assert.isFalse(dialog.open);
      assert.equal(dialog.returnValue, value);

      // Clear button value, confirm textContent is not used as value.
      button.value = 'blah blah';
      button.removeAttribute('value');
      button.textContent = value;
      dialog.show();
      button.focus();  // emulate user focus action
      button.click();

      assert.equal(dialog.returnValue, button.value,
          'don\'t take button textContent as value');
    });
    test('boring form inside dialog', function() {
      var form = document.createElement('form');
      dialog.appendChild(form);  // don't specify method
      form.addEventListener('submit', function(ev) {
        ev.preventDefault();
      });

      var button = document.createElement('button');
      button.value = 'Moot';
      form.appendChild(button);

      dialog.showModal();
      button.focus();  // emulate user focus action
      button.click();

      assert.isTrue(dialog.open, 'non-dialog form should not close dialog')
      assert(!dialog.returnValue);
    });
    test('type="image" submitter', function() {
      var form = document.createElement('form');
      form.setAttribute('method', 'dialog');
      dialog.appendChild(form);
      dialog.show();

      var image = document.createElement('input');
      image.type = 'image';
      image.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
      image.setAttribute('value', 'image should not accept value');
      form.appendChild(image);
      image.click();

      assert.notEqual(image.getAttribute('value'), dialog.returnValue);
      assert.equal(dialog.returnValue, '0,0');
    });
    test('form submitter across dialogs', function() {
      var form1 = document.createElement('form');
      form1.setAttribute('method', 'dialog');
      dialog.appendChild(form1);

      var button1 = document.createElement('button');
      button1.value = 'from form1: first value';
      form1.appendChild(button1);
      dialog.showModal();

      var dialog2 = createDialog();
      dialog2.returnValue = 'dialog2 default close value';
      var form2 = document.createElement('form');
      form2.setAttribute('method', 'dialog');
      dialog2.appendChild(form2);
      dialog2.showModal();

      button1.click();
      assert.isFalse(dialog.open);

      // nb. this never fires 'submit' so the .returnValue can't be wrong: is there another way
      // to submit a form that doesn't involve a click (enter implicitly 'clicks') or submit?
      form2.submit();
      assert.isFalse(dialog2.open);

      assert.equal(dialog2.returnValue, 'dialog2 default close value',
          'second dialog shouldn\'t reuse formSubmitter');
    });
  });

  suite('order', function() {
    test('non-modal unchanged', function() {
      var one = createDialog();
      var two = createDialog();

      one.style.zIndex = 100;
      two.style.zIndex = 200;
      one.show();
      two.show();

      assert.equal(window.getComputedStyle(one).zIndex, 100);
      assert.equal(window.getComputedStyle(two).zIndex, 200);

      two.close();
      assert.equal(window.getComputedStyle(two).zIndex, 200);
    });
    test('modal stacking order', function() {
      dialog.showModal();

      // Create incorrectly-named dialogs: front has a lower z-index, and back
      // has a higher z-index.
      var front = createDialog();
      var back = createDialog();
      front.style.zIndex = 100;
      back.style.zIndex = 200;

      // Show back first, then front. Thus we expect back to be behind front.
      back.showModal();
      front.showModal();

      var zf = +window.getComputedStyle(front).zIndex;
      var zb = +window.getComputedStyle(back).zIndex;
      assert.isAbove(zf, zb, 'showModal order dictates z-index');

      var backBackdrop = back.nextElementSibling;
      var zbb = +window.getComputedStyle(backBackdrop).zIndex;
      assert.equal(backBackdrop.className, 'backdrop');
      assert.isBelow(zbb, zb, 'backdrop below dialog');

      var frontBackdrop = front.nextElementSibling;
      var zfb = +window.getComputedStyle(frontBackdrop).zIndex
      assert.equal(frontBackdrop.className, 'backdrop');
      assert.isBelow(zfb, zf,' backdrop below dialog');

      assert.isAbove(zfb, zb, 'front backdrop is above back dialog');

      front.close();
      assert.notOk(front.style.zIndex, 'modal close should clear zindex');
    });
  });

  suite('press tab key', function() {
    test('tab key', function() {
      var dialog = createDialog();
      dialog.showModal();

      document.documentElement.dispatchEvent(createKeyboardEvent(9));

      var ev = document.createEvent('Events');
      ev.initEvent('focus', true, true);
      document.documentElement.dispatchEvent(ev);

      dialog.close();
    });
  });
}();
