/**
 * @license
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.
 */
// This should be the first import to install handler before any other code
import './source-map-support-install';
// TODO(dmfilippov): remove bundled-polymer.js imports when the following issue
// https://github.com/Polymer/polymer-resin/issues/9 is resolved.
import '../scripts/bundled-polymer';
import '@polymer/iron-test-helpers/iron-test-helpers';
import './test-router';
import {_testOnlyInitAppContext} from './test-app-context-init';
import {_testOnly_resetPluginLoader} from '../elements/shared/gr-js-api-interface/gr-plugin-loader';
import {_testOnlyResetRestApi} from '../elements/shared/gr-js-api-interface/gr-plugin-rest-api';
import {_testOnlyResetGrRestApiSharedObjects} from '../elements/shared/gr-rest-api-interface/gr-rest-api-interface';
import {
  cleanupTestUtils,
  getCleanupsCount,
  registerTestCleanup,
  TestKeyboardShortcutBinder,
} from './test-utils';
import {flushDebouncers} from '@polymer/polymer/lib/utils/debounce';
import {_testOnly_getShortcutManagerInstance} from '../mixins/keyboard-shortcut-mixin/keyboard-shortcut-mixin';
import sinon, {SinonSpy} from 'sinon/pkg/sinon-esm';
import {safeTypesBridge} from '../utils/safe-types-util';
import {_testOnly_initGerritPluginApi} from '../elements/shared/gr-js-api-interface/gr-gerrit';
import {initGlobalVariables} from '../elements/gr-app-global-var-init';
import 'chai/chai';
import {
  _testOnly_defaultResinReportHandler,
  installPolymerResin,
} from '../scripts/polymer-resin-install';
import {hasOwnProperty} from '../utils/common-util';

declare global {
  interface Window {
    assert: typeof chai.assert;
    expect: typeof chai.expect;
    fixture: typeof fixtureImpl;
    stub: typeof stubImpl;
    sinon: typeof sinon;
  }
  let assert: typeof chai.assert;
  let expect: typeof chai.expect;
  let stub: typeof stubImpl;
  let sinon: typeof sinon;
}
window.assert = chai.assert;
window.expect = chai.expect;

window.sinon = sinon;

installPolymerResin(safeTypesBridge, (isViolation, fmt, ...args) => {
  const log = _testOnly_defaultResinReportHandler;
  log(isViolation, fmt, ...args);
  if (isViolation) {
    // This will cause the test to fail if there is a data binding
    // violation.
    throw new Error('polymer-resin violation: ' + fmt + JSON.stringify(args));
  }
});

interface TestFixtureElement extends HTMLElement {
  restore(): void;
  create(model?: unknown): HTMLElement | HTMLElement[];
}

function getFixtureElementById(fixtureId: string) {
  return document.getElementById(fixtureId) as TestFixtureElement;
}

// For karma always set our implementation
// (karma doesn't provide the fixture method)
function fixtureImpl(fixtureId: string, model: unknown) {
  // This method is inspired by web-component-tester method
  registerTestCleanup(() => getFixtureElementById(fixtureId).restore());
  return getFixtureElementById(fixtureId).create(model);
}

window.fixture = fixtureImpl;

setup(() => {
  window.Gerrit = {};
  initGlobalVariables();

  // If the following asserts fails - then window.stub is
  // overwritten by some other code.
  assert.equal(getCleanupsCount(), 0);
  // The following calls is nessecary to avoid influence of previously executed
  // tests.
  TestKeyboardShortcutBinder.push();
  _testOnlyInitAppContext();
  _testOnly_initGerritPluginApi();
  const mgr = _testOnly_getShortcutManagerInstance();
  assert.isTrue(mgr._testOnly_isEmpty());
  const selection = document.getSelection();
  if (selection) {
    selection.removeAllRanges();
  }
  const pl = _testOnly_resetPluginLoader();
  // For testing, always init with empty plugin list
  // Since when serve in gr-app, we always retrieve the list
  // from project config and init loading after that, all
  // `awaitPluginsLoaded` will rely on that to kick off,
  // in testing, we want to kick start this earlier.
  // You still can manually call _testOnly_resetPluginLoader
  // to reset this behavior if you need to test something specific.
  pl.loadPlugins([]);
  _testOnlyResetGrRestApiSharedObjects();
  _testOnlyResetRestApi();
});

// For karma always set our implementation
// (karma doesn't provide the stub method)
function stubImpl<T extends keyof HTMLElementTagNameMap>(
  tagName: T,
  implementation: Partial<HTMLElementTagNameMap[T]>
) {
  // This method is inspired by web-component-tester method
  const proto = document.createElement(tagName).constructor
    .prototype as HTMLElementTagNameMap[T];
  let key: keyof HTMLElementTagNameMap[T];
  const stubs: SinonSpy[] = [];
  for (key in implementation) {
    if (hasOwnProperty(implementation, key)) {
      stubs.push(sinon.stub(proto, key).callsFake(implementation[key]));
    }
  }
  registerTestCleanup(() => {
    stubs.forEach(stub => {
      stub.restore();
    });
  });
}

window.stub = stubImpl;

// Very simple function to catch unexpected elements in documents body.
// It can't catch everything, but in most cases it is enough.
function checkChildAllowed(element: Element) {
  const allowedTags = ['SCRIPT', 'IRON-A11Y-ANNOUNCER'];
  if (allowedTags.includes(element.tagName)) {
    return;
  }
  if (element.tagName === 'TEST-FIXTURE') {
    if (
      element.children.length === 0 ||
      (element.children.length === 1 &&
        element.children[0].tagName === 'TEMPLATE')
    ) {
      return;
    }
    assert.fail(
      `Test fixture
        ${element.outerHTML}` +
        "isn't resotred after the test is finished. Please ensure that " +
        'restore() method is called for this test-fixture. Usually the call' +
        'happens automatically.'
    );
    return;
  }
  if (
    element.tagName === 'DIV' &&
    element.id === 'gr-hovercard-container' &&
    element.childNodes.length === 0
  ) {
    return;
  }
  assert.fail(
    `The following node remains in document after the test:
      ${element.tagName}
      Outer HTML:
      ${element.outerHTML}`
  );
}
function checkGlobalSpace() {
  for (const child of document.body.children) {
    checkChildAllowed(child);
  }
}

teardown(() => {
  sinon.restore();
  cleanupTestUtils();
  TestKeyboardShortcutBinder.pop();
  checkGlobalSpace();
  // Clean Polymer debouncer queue, so next tests will not be affected.
  flushDebouncers();
});
