/**
 * @license
 * Copyright (C) 2020 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.
 */
import './common-test-setup';
import '@polymer/test-fixture/test-fixture';
import 'chai/chai';

declare global {
  interface Window {
    flush: typeof flushImpl;
    fixtureFromTemplate: typeof fixtureFromTemplateImpl;
    fixtureFromElement: typeof fixtureFromElementImpl;
  }
  let flush: typeof flushImpl;
  let fixtureFromTemplate: typeof fixtureFromTemplateImpl;
  let fixtureFromElement: typeof fixtureFromElementImpl;
}

// Workaround for https://github.com/karma-runner/karma-mocha/issues/227
let unhandledError: ErrorEvent;

window.addEventListener('error', e => {
  // For uncaught error mochajs doesn't print the full stack trace.
  // We should print it ourselves.
  console.error('Uncaught error:');
  console.error(e);
  console.error(e.error.stack.toString());
  unhandledError = e;
});

let originalOnBeforeUnload: typeof window.onbeforeunload;

suiteSetup(() => {
  // This suiteSetup() method is called only once before all tests

  // Can't use window.addEventListener("beforeunload",...) here,
  // the handler is raised too late.
  originalOnBeforeUnload = window.onbeforeunload;
  window.onbeforeunload = function (e: BeforeUnloadEvent) {
    // If a test reloads a page, we can't prevent it.
    // However we can print an error and the stack trace with assert.fail
    try {
      throw new Error();
    } catch (e) {
      console.error('Page reloading attempt detected.');
      console.error(e.stack.toString());
    }
    if (originalOnBeforeUnload) {
      originalOnBeforeUnload.call(window, e);
    }
  };
});

suiteTeardown(() => {
  // This suiteTeardown() method is called only once after all tests
  window.onbeforeunload = originalOnBeforeUnload;
  if (unhandledError) {
    throw unhandledError;
  }
});

// Tests can use fake timers (sandbox.useFakeTimers)
// Keep the original one for use in test utils methods.
const nativeSetTimeout = window.setTimeout;

function flushImpl(): Promise<void>;
function flushImpl(callback: () => void): void;
/**
 * Triggers a flush of any pending events, observations, etc and calls you back
 * after they have been processed if callback is passed; otherwise returns
 * promise.
 */
function flushImpl(callback?: () => void): Promise<void> | void {
  // Ideally, this function would be a call to Polymer.dom.flush, but that
  // doesn't support a callback yet
  // (https://github.com/Polymer/polymer-dev/issues/851)
  // The type is used only in one place, disable eslint warning instead of
  // creating an interface
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  (window as any).Polymer.dom.flush();
  if (callback) {
    nativeSetTimeout(callback, 0);
  } else {
    return new Promise(resolve => {
      nativeSetTimeout(resolve, 0);
    });
  }
}

self.flush = flushImpl;

class TestFixtureIdProvider {
  public static readonly instance: TestFixtureIdProvider =
    new TestFixtureIdProvider();

  private fixturesCount = 1;

  generateNewFixtureId() {
    this.fixturesCount++;
    return `fixture-${this.fixturesCount}`;
  }
}

interface TagTestFixture<T extends Element> {
  instantiate(model?: unknown): T;
}

class TestFixture {
  constructor(readonly fixtureId: string) {}

  /**
   * Create an instance of a fixture's template.
   *
   * @param model - see Data-bound sections at
   *   https://www.webcomponents.org/element/@polymer/test-fixture
   * @return - if the fixture's template contains
   *   a single element, returns the appropriated instantiated element.
   *   Otherwise, it return an array of all instantiated elements from the
   *   template.
   */
  instantiate(model?: unknown): HTMLElement | HTMLElement[] {
    // The window.fixture method is defined in common-test-setup.js
    return window.fixture(this.fixtureId, model);
  }
}

/**
 * Wraps provided template to a test-fixture tag and adds test-fixture to
 * the document. You can use the html function to create a template.
 *
 * Example:
 * import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 *
 * // Create fixture at the root level of a test file
 * const basicTestFixture = fixtureFromTemplate(html`
 *   <gr-cursor-manager cursor-target-class="targeted"></gr-cursor-manager>
 *   <ul>
 *    <li>A</li>
 *    <li>B</li>
 *    <li>C</li>
 *    <li>D</li>
 *   </ul>
 * `);
 * ...
 * // Instantiate fixture when needed:
 *
 * suite('example') {
 *   let elements;
 *   setup(() => {
 *     elements = basicTestFixture.instantiate();
 *   });
 * }
 *
 * @param template - a template for a fixture
 */
function fixtureFromTemplateImpl(template: HTMLTemplateElement): TestFixture {
  const fixtureId = TestFixtureIdProvider.instance.generateNewFixtureId();
  const testFixture = document.createElement('test-fixture');
  testFixture.setAttribute('id', fixtureId);
  testFixture.appendChild(template);
  document.body.appendChild(testFixture);
  return new TestFixture(fixtureId);
}

/**
 * Wraps provided tag to a test-fixture/template tags and adds test-fixture
 * to the document.
 *
 * Example:
 *
 * // Create fixture at the root level of a test file
 * const basicTestFixture = fixtureFromElement('gr-diff-view');
 * ...
 * // Instantiate fixture when needed:
 *
 * suite('example') {
 *   let element;
 *   setup(() => {
 *     element = basicTestFixture.instantiate();
 *   });
 * }
 *
 * @param tagName - a template for a fixture is <tagName></tagName>
 */
function fixtureFromElementImpl<T extends keyof HTMLElementTagNameMap>(
  tagName: T
): TagTestFixture<HTMLElementTagNameMap[T]> {
  const template = document.createElement('template');
  template.innerHTML = `<${tagName}></${tagName}>`;
  return fixtureFromTemplate(template) as unknown as TagTestFixture<
    HTMLElementTagNameMap[T]
  >;
}

window.fixtureFromTemplate = fixtureFromTemplateImpl;
window.fixtureFromElement = fixtureFromElementImpl;
