/**
 * @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';
import {pluginEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints.js';
import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.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);
    }
    pluginEndpoints.onDetachedEndpoint(this.name, this._endpointCallBack);
  }

  /**
   * @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();
    this._endpointCallBack = this._initModule.bind(this);
    pluginEndpoints.onNewEndpoint(this.name, this._endpointCallBack);
    pluginLoader.awaitPluginsLoaded()
        .then(() => Promise.all(
            pluginEndpoints.getPlugins(this.name).map(
                pluginUrl => this._import(pluginUrl)))
        )
        .then(() =>
          pluginEndpoints
              .getDetails(this.name)
              .forEach(this._initModule, this)
        );
  }
}

customElements.define(GrEndpointDecorator.is, GrEndpointDecorator);
