/**
 * @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.
 */
import '../../../scripts/bundled-polymer.js';

import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
import {importHref} from '../../../scripts/import-href.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {GestureEventListeners} from '@polymer/polymer/lib/mixins/gesture-event-listeners.js';
import {LegacyElementMixin} from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
import {htmlTemplate} from './gr-endpoint-decorator_html.js';

const INIT_PROPERTIES_TIMEOUT_MS = 10000;

/** @extends Polymer.Element */
class GrEndpointDecorator extends GestureEventListeners(
    LegacyElementMixin(
        PolymerElement)) {
  static get template() { return htmlTemplate; }

  static get is() { return 'gr-endpoint-decorator'; }

  static get properties() {
    return {
      name: String,
      /** @type {!Map} */
      _domHooks: {
        type: Map,
        value() { return new Map(); },
      },
      /**
       * This map prevents importing the same endpoint twice.
       * Without caching, if a plugin is loaded after the loaded plugins
       * callback fires, it will be imported twice and appear twice on the page.
       *
       * @type {!Map}
       */
      _initializedPlugins: {
        type: Map,
        value() { return new Map(); },
      },
    };
  }

  /** @override */
  detached() {
    super.detached();
    for (const [el, domHook] of this._domHooks) {
      domHook.handleInstanceDetached(el);
    }
  }

  /**
   * @suppress {checkTypes}
   */
  _import(url) {
    return new Promise((resolve, reject) => {
      importHref(url, resolve, reject);
    });
  }

  _initDecoration(name, plugin) {
    const el = document.createElement(name);
    return this._initProperties(el, plugin,
        this.getContentChildren().find(
            el => el.nodeName !== 'GR-ENDPOINT-PARAM'))
        .then(el => this._appendChild(el));
  }

  _initReplacement(name, plugin) {
    this.getContentChildNodes()
        .filter(node => node.nodeName !== 'GR-ENDPOINT-PARAM')
        .forEach(node => node.remove());
    const el = document.createElement(name);
    return this._initProperties(el, plugin).then(
        el => this._appendChild(el));
  }

  _getEndpointParams() {
    return Array.from(
        dom(this).querySelectorAll('gr-endpoint-param'));
  }

  /**
   * @param {!Element} el
   * @param {!Object} plugin
   * @param {!Element=} opt_content
   * @return {!Promise<Element>}
   */
  _initProperties(el, plugin, opt_content) {
    el.plugin = plugin;
    if (opt_content) {
      el.content = opt_content;
    }
    const expectProperties = this._getEndpointParams().map(paramEl => {
      const helper = plugin.attributeHelper(paramEl);
      const paramName = paramEl.getAttribute('name');
      return helper.get('value').then(
          value => helper.bind('value',
              value => plugin.attributeHelper(el).set(paramName, value))
      );
    });
    let timeoutId;
    const timeout = new Promise(
        resolve => timeoutId = setTimeout(() => {
          console.warn(
              'Timeout waiting for endpoint properties initialization: ' +
            `plugin ${plugin.getPluginName()}, endpoint ${this.name}`);
        }, INIT_PROPERTIES_TIMEOUT_MS));
    return Promise.race([timeout, Promise.all(expectProperties)])
        .then(() => {
          clearTimeout(timeoutId);
          return el;
        });
  }

  _appendChild(el) {
    return dom(this.root).appendChild(el);
  }

  _initModule({moduleName, plugin, type, domHook}) {
    const name = plugin.getPluginName() + '.' + moduleName;
    if (this._initializedPlugins.get(name)) {
      return;
    }
    let initPromise;
    switch (type) {
      case 'decorate':
        initPromise = this._initDecoration(moduleName, plugin);
        break;
      case 'replace':
        initPromise = this._initReplacement(moduleName, plugin);
        break;
    }
    if (!initPromise) {
      console.warn('Unable to initialize module ' + name);
    }
    this._initializedPlugins.set(name, true);
    initPromise.then(el => {
      domHook.handleInstanceAttached(el);
      this._domHooks.set(el, domHook);
    });
  }

  /** @override */
  ready() {
    super.ready();
    Gerrit._endpoints.onNewEndpoint(this.name, this._initModule.bind(this));
    Gerrit.awaitPluginsLoaded()
        .then(() => Promise.all(
            Gerrit._endpoints.getPlugins(this.name).map(
                pluginUrl => this._import(pluginUrl)))
        )
        .then(() =>
          Gerrit._endpoints
              .getDetails(this.name)
              .forEach(this._initModule, this)
        );
  }
}

customElements.define(GrEndpointDecorator.is, GrEndpointDecorator);
