/**
 * @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.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 earror 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(this, 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(private 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;
