/**
 * @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 {importHref} from '../../../scripts/import-href';
import {HookApi, PluginApi} from '../../plugins/gr-plugin-types';
import {notUndefined} from '../../../types/types';

type Callback = (value: any) => void;

export interface ModuleInfo {
  moduleName: string;
  plugin: PluginApi;
  pluginUrl?: URL;
  type?: string;
  domHook?: HookApi;
  slot?: string;
}

interface Options {
  endpoint: string;
  dynamicEndpoint?: string;
  slot?: string;
  type?: string;
  moduleName?: string;
  domHook?: HookApi;
}

export class GrPluginEndpoints {
  private readonly _endpoints = new Map<string, ModuleInfo[]>();

  private readonly _callbacks = new Map<string, ((value: any) => void)[]>();

  private readonly _dynamicPlugins = new Map<string, Set<string>>();

  private readonly _importedUrls = new Set<string>();

  private _pluginLoaded = false;

  setPluginsReady() {
    this._pluginLoaded = true;
  }

  onNewEndpoint(endpoint: string, callback: Callback) {
    if (!this._callbacks.has(endpoint)) {
      this._callbacks.set(endpoint, []);
    }
    this._callbacks.get(endpoint)!.push(callback);
  }

  onDetachedEndpoint(endpoint: string, callback: Callback) {
    if (this._callbacks.has(endpoint)) {
      const filteredCallbacks = this._callbacks
        .get(endpoint)!
        .filter((cb: Callback) => cb !== callback);
      this._callbacks.set(endpoint, filteredCallbacks);
    }
  }

  _getOrCreateModuleInfo(plugin: PluginApi, opts: Options): ModuleInfo {
    const {endpoint, slot, type, moduleName, domHook} = opts;
    const existingModule = this._endpoints
      .get(endpoint!)!
      .find(
        (info: ModuleInfo) =>
          info.plugin === plugin &&
          info.moduleName === moduleName &&
          info.domHook === domHook &&
          info.slot === slot
      );
    if (existingModule) {
      return existingModule;
    } else {
      const newModule: ModuleInfo = {
        moduleName: moduleName!,
        plugin,
        pluginUrl: plugin._url,
        type,
        domHook,
        slot,
      };
      this._endpoints.get(endpoint!)!.push(newModule);
      return newModule;
    }
  }

  /**
   * Register a plugin to an endpoint.
   *
   * Dynamic plugins are registered to a specific prefix, such as
   * 'change-list-header'. These plugins are then fetched by prefix to determine
   * which endpoints to dynamically add to the page.
   */
  registerModule(plugin: PluginApi, opts: Options) {
    const endpoint = opts.endpoint!;
    const dynamicEndpoint = opts.dynamicEndpoint;
    if (dynamicEndpoint) {
      if (!this._dynamicPlugins.has(dynamicEndpoint)) {
        this._dynamicPlugins.set(dynamicEndpoint, new Set());
      }
      this._dynamicPlugins.get(dynamicEndpoint)!.add(endpoint);
    }
    if (!this._endpoints.has(endpoint)) {
      this._endpoints.set(endpoint, []);
    }
    const moduleInfo = this._getOrCreateModuleInfo(plugin, opts);
    // TODO: the logic below seems wrong when:
    // multiple plugins register to the same endpoint
    // one register before plugins ready
    // the other done after, then only the later one will have the callbacks
    // invoked.
    if (this._pluginLoaded && this._callbacks.has(endpoint)) {
      this._callbacks.get(endpoint)!.forEach(callback => callback(moduleInfo));
    }
  }

  getDynamicEndpoints(dynamicEndpoint: string): string[] {
    const plugins = this._dynamicPlugins.get(dynamicEndpoint);
    if (!plugins) return [];
    return Array.from(plugins);
  }

  /**
   * Get detailed information about modules registered with an extension
   * endpoint.
   */
  getDetails(name: string, options?: Options): ModuleInfo[] {
    const type = options && options.type;
    const moduleName = options && options.moduleName;
    if (!this._endpoints.has(name)) {
      return [];
    } else {
      return this._endpoints
        .get(name)!
        .filter(
          (item: ModuleInfo) =>
            (!type || item.type === type) &&
            (!moduleName || moduleName === item.moduleName)
        );
    }
  }

  /**
   * Get detailed module names for instantiating at the endpoint.
   */
  getModules(name: string, options?: Options): string[] {
    const modulesData = this.getDetails(name, options);
    if (!modulesData.length) {
      return [];
    }
    return modulesData.map(m => m.moduleName);
  }

  /**
   * Get plugin URLs with element and module definitions.
   */
  getPlugins(name: string, options?: Options): URL[] {
    const modulesData = this.getDetails(name, options);
    if (!modulesData.length) {
      return [];
    }
    return Array.from(new Set(modulesData.map(m => m.pluginUrl))).filter(
      notUndefined
    );
  }

  importUrl(pluginUrl: URL) {
    let timerId: any;
    return Promise.race([
      new Promise((resolve, reject) => {
        this._importedUrls.add(pluginUrl.href);
        importHref(pluginUrl.href, resolve, reject);
      }),
      // Timeout after 3s
      new Promise(r => (timerId = setTimeout(r, 3000))),
    ]).finally(() => {
      if (timerId) clearTimeout(timerId);
    });
  }

  /**
   * Get plugin URLs with element and module definitions.
   */
  getAndImportPlugins(name: string, options?: Options) {
    return Promise.all(
      this.getPlugins(name, options).map(pluginUrl => {
        if (this._importedUrls.has(pluginUrl.href)) {
          return Promise.resolve();
        }

        // TODO: we will deprecate html plugins entirely
        // for now, keep the original behavior and import
        // only for html ones
        if (pluginUrl?.pathname.endsWith('.html')) {
          return this.importUrl(pluginUrl);
        } else {
          return Promise.resolve();
        }
      })
    );
  }
}

// TODO(dmfilippov): Convert to service and add to appContext
let pluginEndpoints = new GrPluginEndpoints();

// To avoid mutable-exports, we don't want to export above variable directly
export function getPluginEndpoints() {
  return pluginEndpoints;
}
export function _testOnly_resetEndpoints() {
  pluginEndpoints = new GrPluginEndpoints();
}
