/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import {PLUGIN_LOADING_TIMEOUT_MS} from './gr-api-utils';
import {PluginLoader} from './gr-plugin-loader';
import {stubBaseUrl, waitEventLoop} from '../../../test/test-utils';
import {addListenerForTest, stubRestApi} from '../../../test/test-utils';
import {PluginApi} from '../../../api/plugin';
import {SinonFakeTimers} from 'sinon';
import {Timestamp} from '../../../api/rest-api';
import {assert} from '@open-wc/testing';
import {getAppContext} from '../../../services/app-context';

suite('gr-plugin-loader tests', () => {
  let plugin: PluginApi;

  let url: string;
  let pluginLoader: PluginLoader;
  let clock: SinonFakeTimers;
  let bodyStub: sinon.SinonStub;

  setup(() => {
    clock = sinon.useFakeTimers();

    stubRestApi('getAccount').returns(
      Promise.resolve({name: 'Judy Hopps', registered_on: '' as Timestamp})
    );
    stubRestApi('send').returns(
      Promise.resolve({...new Response(), status: 200})
    );
    pluginLoader = new PluginLoader(
      getAppContext().reportingService,
      getAppContext().restApiService
    );
    bodyStub = sinon.stub(document.body, 'appendChild');
    url = window.location.origin;
  });

  teardown(() => {
    clock.restore();
  });

  test('reuse plugin for install calls', () => {
    pluginLoader.install(
      p => {
        plugin = p;
      },
      '0.1',
      'http://test.com/plugins/testplugin/static/test.js'
    );

    let otherPlugin;
    pluginLoader.install(
      p => {
        otherPlugin = p;
      },
      '0.1',
      'http://test.com/plugins/testplugin/static/test.js'
    );
    assert.strictEqual(plugin, otherPlugin);
  });

  test('versioning', () => {
    const callback = sinon.spy();
    pluginLoader.install(callback, '0.0pre-alpha');
    assert(callback.notCalled);
  });

  test('report pluginsLoaded', async () => {
    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );
    pluginsLoadedStub.reset();
    pluginLoader.loadPlugins([]);
    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.called);
  });

  test('arePluginsLoaded', async () => {
    assert.isFalse(pluginLoader.arePluginsLoaded());
    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
    ];

    pluginLoader.loadPlugins(plugins);
    assert.isFalse(pluginLoader.arePluginsLoaded());
    // Timeout on loading plugins
    clock.tick(PLUGIN_LOADING_TIMEOUT_MS * 2);

    await waitEventLoop();
    assert.isTrue(pluginLoader.arePluginsLoaded());
  });

  test('plugins installed successfully', async () => {
    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(() => void 0, undefined, url);
    });
    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );

    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
    ];
    pluginLoader.loadPlugins(plugins);

    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo', 'bar']));
    assert.isTrue(pluginLoader.arePluginsLoaded());
  });

  test('isPluginEnabled and isPluginLoaded', async () => {
    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(() => void 0, undefined, url);
    });

    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
      'bar/static/test.js',
    ];
    pluginLoader.loadPlugins(plugins);
    assert.isTrue(
      plugins.every(plugin => pluginLoader.isPluginEnabled(plugin))
    );

    await waitEventLoop();
    assert.isTrue(pluginLoader.arePluginsLoaded());
    assert.isTrue(plugins.every(plugin => pluginLoader.isPluginLoaded(plugin)));
  });

  test('plugins installed mixed result, 1 fail 1 succeed', async () => {
    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
    ];

    const alertStub = sinon.stub();
    addListenerForTest(document, 'show-alert', alertStub);

    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(
        () => {
          if (url === plugins[0]) {
            throw new Error('failed');
          }
        },
        undefined,
        url
      );
    });

    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );

    pluginLoader.loadPlugins(plugins);

    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.calledWithExactly(['bar']));
    assert.isTrue(pluginLoader.arePluginsLoaded());
    assert.isTrue(alertStub.calledOnce);
  });

  test('isPluginEnabled and isPluginLoaded for mixed results', async () => {
    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
    ];

    const alertStub = sinon.stub();
    addListenerForTest(document, 'show-alert', alertStub);

    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(
        () => {
          if (url === plugins[0]) {
            throw new Error('failed');
          }
        },
        undefined,
        url
      );
    });

    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );

    pluginLoader.loadPlugins(plugins);
    assert.isTrue(
      plugins.every(plugin => pluginLoader.isPluginEnabled(plugin))
    );

    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.calledWithExactly(['bar']));
    assert.isTrue(pluginLoader.arePluginsLoaded());
    assert.isTrue(alertStub.calledOnce);
    assert.isTrue(pluginLoader.isPluginLoaded(plugins[1]));
    assert.isFalse(pluginLoader.isPluginLoaded(plugins[0]));
  });

  test('plugins installed all failed', async () => {
    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
    ];

    const alertStub = sinon.stub();
    addListenerForTest(document, 'show-alert', alertStub);

    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(
        () => {
          throw new Error('failed');
        },
        undefined,
        url
      );
    });

    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );

    pluginLoader.loadPlugins(plugins);

    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.calledWithExactly([]));
    assert.isTrue(pluginLoader.arePluginsLoaded());
    assert.isTrue(alertStub.calledTwice);
  });

  test('plugins installed failed because of wrong version', async () => {
    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/bar/static/test.js',
    ];

    const alertStub = sinon.stub();
    addListenerForTest(document, 'show-alert', alertStub);

    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(() => {}, url === plugins[0] ? '' : 'alpha', url);
    });

    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );

    pluginLoader.loadPlugins(plugins);

    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo']));
    assert.isTrue(pluginLoader.arePluginsLoaded());
    assert.isTrue(alertStub.calledOnce);
  });

  test('multiple assets for same plugin installed successfully', async () => {
    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(() => void 0, undefined, url);
    });
    const pluginsLoadedStub = sinon.stub(
      getAppContext().reportingService,
      'pluginsLoaded'
    );

    const plugins = [
      'http://test.com/plugins/foo/static/test.js',
      'http://test.com/plugins/foo/static/test2.js',
      'http://test.com/plugins/bar/static/test.js',
    ];
    pluginLoader.loadPlugins(plugins);

    await waitEventLoop();
    assert.isTrue(pluginsLoadedStub.calledWithExactly(['foo', 'bar']));
    assert.isTrue(pluginLoader.arePluginsLoaded());
  });

  suite('plugin path and url', () => {
    let loadJsPluginStub: sinon.SinonStub;
    setup(() => {
      loadJsPluginStub = sinon.stub();
      sinon
        .stub(pluginLoader, 'createScriptTag')
        .callsFake((url: string, _onerror?: OnErrorEventHandler | undefined) =>
          loadJsPluginStub(url)
        );
    });

    test('invalid plugin path', () => {
      const failToLoadStub = sinon.stub();
      sinon.stub(pluginLoader, 'failToLoad').callsFake((...args) => {
        failToLoadStub(...args);
      });

      pluginLoader.loadPlugins(['foo/bar']);

      assert.isTrue(failToLoadStub.calledOnce);
      assert.isTrue(
        failToLoadStub.calledWithExactly(
          'Unrecognized plugin path foo/bar',
          'foo/bar'
        )
      );
    });

    test('relative path for plugins', () => {
      pluginLoader.loadPlugins(['foo/bar.js']);

      assert.isTrue(loadJsPluginStub.calledOnce);
      assert.isTrue(loadJsPluginStub.calledWithExactly(`${url}/foo/bar.js`));
    });

    test('relative path should honor getBaseUrl', () => {
      const testUrl = '/test';
      stubBaseUrl(testUrl);

      pluginLoader.loadPlugins(['foo/bar.js']);

      assert.isTrue(loadJsPluginStub.calledOnce);
      assert.isTrue(
        loadJsPluginStub.calledWithExactly(`${url}${testUrl}/foo/bar.js`)
      );
    });

    test('absolute path for plugins', () => {
      pluginLoader.loadPlugins(['http://e.com/foo/bar.js']);

      assert.isTrue(loadJsPluginStub.calledOnce);
      assert.isTrue(
        loadJsPluginStub.calledWithExactly('http://e.com/foo/bar.js')
      );
    });
  });

  suite('With ASSETS_PATH', () => {
    let loadJsPluginStub: sinon.SinonStub;
    setup(() => {
      window.ASSETS_PATH = 'https://cdn.com';
      loadJsPluginStub = sinon.stub();
      sinon
        .stub(pluginLoader, 'createScriptTag')
        .callsFake((url: string, _onerror?: OnErrorEventHandler | undefined) =>
          loadJsPluginStub(url)
        );
    });

    teardown(() => {
      window.ASSETS_PATH = '';
    });

    test('Should try load plugins from assets path instead', () => {
      pluginLoader.loadPlugins(['foo/bar.js']);

      assert.isTrue(loadJsPluginStub.calledOnce);
      assert.isTrue(
        loadJsPluginStub.calledWithExactly('https://cdn.com/foo/bar.js')
      );
    });

    test('Should honor original path if exists', () => {
      pluginLoader.loadPlugins(['http://e.com/foo/bar.js']);

      assert.isTrue(loadJsPluginStub.calledOnce);
      assert.isTrue(
        loadJsPluginStub.calledWithExactly('http://e.com/foo/bar.js')
      );
    });

    test('Should try replace current host with assetsPath', () => {
      const host = window.location.origin;
      pluginLoader.loadPlugins([`${host}/foo/bar.js`]);

      assert.isTrue(loadJsPluginStub.calledOnce);
      assert.isTrue(
        loadJsPluginStub.calledWithExactly('https://cdn.com/foo/bar.js')
      );
    });
  });

  test('adds js plugins will call the body', () => {
    pluginLoader.loadPlugins([
      'http://e.com/foo/bar.js',
      'http://e.com/bar/foo.js',
    ]);
    assert.isTrue(bodyStub.calledTwice);
  });

  test('can call awaitPluginsLoaded multiple times', async () => {
    const plugins = ['http://e.com/foo/bar.js', 'http://e.com/bar/foo.js'];

    let installed = false;
    function pluginCallback(url: string) {
      if (url === plugins[1]) {
        installed = true;
      }
    }
    sinon.stub(pluginLoader, 'loadJsPlugin').callsFake(url => {
      pluginLoader.install(() => pluginCallback(url), undefined, url);
    });

    pluginLoader.loadPlugins(plugins);

    await pluginLoader.awaitPluginsLoaded();
    assert.isTrue(installed);
    await pluginLoader.awaitPluginsLoaded();
  });
});
