/**
 * @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 {PluginApi} from '../../../api/plugin';
import {notUndefined} from '../../../types/types';
import {HookApi} from '../../../api/hook';
import {appContext} from '../../../services/app-context';
import {Execution} from '../../../constants/reporting';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
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[]>();

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  private readonly _callbacks = new Map<string, ((value: any) => void)[]>();

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

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

  private readonly reporting = appContext.reportingService;

  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) {
    this.reporting.reportExecution(Execution.METHOD_USED, {
      id: 'import-href-endpoints',
      pluginUrl,
    });
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    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();
}
