/**
 * @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;

  Polymer({
    is: 'gr-endpoint-decorator',
    _legacyUndefinedCheck: true,

    properties: {
      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(); },
      },
    },

    detached() {
      for (const [el, domHook] of this._domHooks) {
        domHook.handleInstanceDetached(el);
      }
      Gerrit._endpoints.onDetachedEndpoint(this.name, this._endpointCallBack);
    },

    _import(url) {
      return new Promise((resolve, reject) => {
        this.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() {
      // Polymer2: querySelectorAll returns NodeList instead of Array.
      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);
      });
    },

    ready() {
      this._endpointCallBack = this._initModule.bind(this);
      Gerrit._endpoints.onNewEndpoint(this.name, this._endpointCallBack);
      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)
      );
    },
  });
})();
