/**
 * @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.
 */
(function() {
  'use strict';

  const INIT_PROPERTIES_TIMEOUT_MS = 10000;

  /** @extends Polymer.Element */
  class GrEndpointDecorator extends Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element)) {
    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) => {
        (this.importHref || Polymer.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(
          Polymer.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 Polymer.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);
})();
