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

  Polymer({
    is: 'gr-plugin-host',

    properties: {
      config: {
        type: Object,
        observer: '_configChanged',
      },
    },

    behaviors: [
      Gerrit.BaseUrlBehavior,
    ],

    _configChanged(config) {
      const plugins = config.plugin;
      const htmlPlugins = (plugins.html_resource_paths || [])
          .map(p => this._urlFor(p))
          .filter(p => !Gerrit._isPluginPreloaded(p));
      const jsPlugins =
          this._handleMigrations(plugins.js_resource_paths || [], htmlPlugins)
          .map(p => this._urlFor(p))
          .filter(p => !Gerrit._isPluginPreloaded(p));
      const shouldLoadTheme = config.default_theme &&
            !Gerrit._isPluginPreloaded('preloaded:gerrit-theme');
      const defaultTheme =
            shouldLoadTheme ? this._urlFor(config.default_theme) : null;
      const pluginsPending =
          [].concat(jsPlugins, htmlPlugins, defaultTheme || []);
      Gerrit._setPluginsPending(pluginsPending);
      if (defaultTheme) {
        // Make theme first to be first to load.
        // Load sync to work around rare theme loading race condition.
        this._importHtmlPlugins([defaultTheme], true);
      }
      this._loadJsPlugins(jsPlugins);
      this._importHtmlPlugins(htmlPlugins);
    },

    /**
     * Omit .js plugins that have .html counterparts.
     * For example, if plugin provides foo.js and foo.html, skip foo.js.
     */
    _handleMigrations(jsPlugins, htmlPlugins) {
      return jsPlugins.filter(url => {
        const counterpart = url.replace(/\.js$/, '.html');
        return !htmlPlugins.includes(counterpart);
      });
    },

    /**
     * @suppress {checkTypes}
     * States that it expects no more than 3 parameters, but that's not true.
     * @todo (beckysiegel) check Polymer annotations and submit change.
     * @param {Array} plugins
     * @param {boolean=} opt_sync
     */
    _importHtmlPlugins(plugins, opt_sync) {
      const async = !opt_sync;
      for (const url of plugins) {
        // onload (second param) needs to be a function. When null or undefined
        // were passed, plugins were not loaded correctly.
        this.importHref(
            this._urlFor(url), () => {},
            Gerrit._pluginInstallError.bind(null, `${url} import error`),
            async);
      }
    },

    _loadJsPlugins(plugins) {
      for (const url of plugins) {
        this._createScriptTag(this._urlFor(url));
      }
    },

    _createScriptTag(url) {
      const el = document.createElement('script');
      el.defer = true;
      el.src = url;
      el.onerror = Gerrit._pluginInstallError.bind(null, `${url} load error`);
      return document.body.appendChild(el);
    },

    _urlFor(pathOrUrl) {
      if (!pathOrUrl) {
        return pathOrUrl;
      }
      if (pathOrUrl.startsWith('preloaded:') ||
          pathOrUrl.startsWith('http')) {
        // Plugins are loaded from another domain or preloaded.
        return pathOrUrl;
      }
      if (!pathOrUrl.startsWith('/')) {
        pathOrUrl = '/' + pathOrUrl;
      }
      return window.location.origin + this.getBaseUrl() + pathOrUrl;
    },
  });
})();
