/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../test/common-test-setup';
import './gr-js-api-interface';
import {GrPopupInterface} from '../../plugins/gr-popup-interface/gr-popup-interface';
import {EventType} from '../../../api/plugin';
import {PLUGIN_LOADING_TIMEOUT_MS} from './gr-api-utils';
import {
  stubBaseUrl,
  stubRestApi,
  waitEventLoop,
  waitUntilCalled,
} from '../../../test/test-utils';
import {assert} from '@open-wc/testing';
import {testResolver} from '../../../test/common-test-setup';
import {PluginLoader, pluginLoaderToken} from './gr-plugin-loader';
import {SinonFakeTimers, SinonStub, stub, useFakeTimers} from 'sinon';
import {GrJsApiInterface} from './gr-js-api-interface-element';
import {Plugin} from './gr-public-js-api';
import {
  ChangeInfo,
  NumericChangeId,
  PatchSetNum,
  RevisionPatchSetNum,
  Timestamp,
} from '../../../api/rest-api';
import {ParsedChangeInfo} from '../../../types/types';
import {
  createChange,
  createParsedChange,
  createRevision,
} from '../../../test/test-data-generators';
import {EventCallback} from './gr-js-api-types';
import {EmojiSuggestion} from '../gr-suggestion-textarea/gr-suggestion-textarea';

suite('GrJsApiInterface tests', () => {
  let element: GrJsApiInterface;
  let plugin: Plugin;
  let errorStub: SinonStub;
  let loadJsPluginStub: SinonStub;
  let pluginLoader: PluginLoader;

  let clock: SinonFakeTimers;

  const throwErrFn = function () {
    throw Error('Unfortunately, this handler has stopped');
  };

  setup(() => {
    clock = useFakeTimers({shouldClearNativeTimers: true});

    stubRestApi('getAccount').resolves({
      name: 'Judy Hopps',
      registered_on: '' as Timestamp,
    });
    pluginLoader = testResolver(pluginLoaderToken);

    // We are using the jsApiService as the implementation class rather than the
    // interface to better set up tests.
    element = pluginLoader.jsApiService as GrJsApiInterface;
    errorStub = stub(element.reporting, 'error');
    pluginLoader.install(
      p => {
        // We are using the plugin API as the implementation class rather than
        // the interface to better set up tests.
        plugin = p as Plugin;
      },
      '0.1',
      'http://test.com/plugins/testplugin/static/test.js'
    );
    testResolver(pluginLoaderToken).loadPlugins([]);
    loadJsPluginStub = stub(pluginLoader, 'loadJsPlugin');
  });

  teardown(() => {
    clock.restore();
    loadJsPluginStub.restore();
    element._removeEventCallbacks();
  });

  test('url', () => {
    assert.equal(plugin.url(), 'http://test.com/plugins/testplugin/');
    assert.equal(
      plugin.url('/static/test.js'),
      'http://test.com/plugins/testplugin/static/test.js'
    );
  });

  test('showchange event', async () => {
    const showChangeStub = stub();
    const testChange: ParsedChangeInfo = {
      ...createParsedChange(),
      _number: 42 as NumericChangeId,
      revisions: {
        def: {...createRevision(), _number: 2 as RevisionPatchSetNum},
        abc: {...createRevision(), _number: 1 as RevisionPatchSetNum},
      },
    };
    const expectedChange = {mergeable: false, ...testChange};

    plugin.on(EventType.SHOW_CHANGE, throwErrFn);
    plugin.on(EventType.SHOW_CHANGE, showChangeStub);
    element.handleShowChange({
      change: testChange,
      patchNum: 1 as PatchSetNum,
      info: {mergeable: false},
    });
    await waitUntilCalled(showChangeStub, 'showChangeStub');

    const [change, revision, info] = showChangeStub.firstCall.args;
    assert.deepEqual(change, expectedChange);
    assert.deepEqual(revision, testChange.revisions.abc);
    assert.deepEqual(info, {mergeable: false});
    assert.isTrue(errorStub.calledOnce);
  });

  test('show-revision-actions event', async () => {
    const showRevisionActionsStub = stub();
    const testChange: ChangeInfo = {
      ...createChange(),
      _number: 42 as NumericChangeId,
      revisions: {
        def: {...createRevision(), _number: 2 as RevisionPatchSetNum},
        abc: {...createRevision(), _number: 1 as RevisionPatchSetNum},
      },
    };

    plugin.on(EventType.SHOW_REVISION_ACTIONS, throwErrFn);
    plugin.on(EventType.SHOW_REVISION_ACTIONS, showRevisionActionsStub);
    element.handleShowRevisionActions({
      change: testChange,
      revisionActions: {test: {}},
    });
    await waitUntilCalled(showRevisionActionsStub, 'showRevisionActionsStub');

    const [actions, change] = showRevisionActionsStub.firstCall.args;
    assert.deepEqual(change, testChange);
    assert.deepEqual(actions, {test: {}});
    assert.isTrue(errorStub.calledOnce);
  });

  test('handleShowChange awaits plugins load', async () => {
    const testChange: ParsedChangeInfo = {
      ...createParsedChange(),
      _number: 42 as NumericChangeId,
      revisions: {
        def: {...createRevision(), _number: 2 as RevisionPatchSetNum},
        abc: {...createRevision(), _number: 1 as RevisionPatchSetNum},
      },
    };
    const showChangeStub = stub();
    testResolver(pluginLoaderToken).loadPlugins(['plugins/test.js']);
    plugin.on(EventType.SHOW_CHANGE, showChangeStub);
    element.handleShowChange({
      change: testChange,
      patchNum: 1 as PatchSetNum,
      info: {mergeable: null},
    });
    assert.isFalse(showChangeStub.called);

    // Timeout on loading plugins
    clock.tick(PLUGIN_LOADING_TIMEOUT_MS * 2);

    await waitEventLoop();
    assert.isTrue(showChangeStub.called);
  });

  test('custom-emoji event', async () => {
    const customEmojisStub = stub();
    const emojis: EmojiSuggestion[] = [
      {
        value: '😂',
        match: 'noooooooo',
      },
    ];

    plugin.on(EventType.CUSTOM_EMOJIS, throwErrFn);
    plugin.on(EventType.CUSTOM_EMOJIS, customEmojisStub);
    element.modifyEmojis(emojis);
    await waitUntilCalled(customEmojisStub, 'customEmojisStub');

    const [customEmojis] = customEmojisStub.firstCall.args;
    assert.deepEqual(customEmojis, emojis);
    assert.isTrue(errorStub.calledOnce);
  });

  test('revert event', () => {
    function appendToRevertMsg(
      _c: unknown,
      revertMsg: string,
      originalMsg: string
    ) {
      return revertMsg + '\n' + originalMsg.replace(/^/gm, '> ') + '\ninfo';
    }
    const change = createChange();

    assert.equal(element.modifyRevertMsg(change, 'test', 'origTest'), 'test');
    assert.equal(errorStub.callCount, 0);

    plugin.on(EventType.REVERT, throwErrFn);
    plugin.on(EventType.REVERT, appendToRevertMsg);
    assert.equal(
      element.modifyRevertMsg(change, 'test', 'origTest'),
      'test\n> origTest\ninfo'
    );
    assert.isTrue(errorStub.calledOnce);

    plugin.on(EventType.REVERT, appendToRevertMsg);
    assert.equal(
      element.modifyRevertMsg(change, 'test', 'origTest'),
      'test\n> origTest\ninfo\n> origTest\ninfo'
    );
    assert.isTrue(errorStub.calledTwice);
  });

  test('postrevert event labels', () => {
    function getLabels(_c: unknown) {
      return {'Code-Review': 1};
    }

    assert.deepEqual(element.getReviewPostRevert(undefined), {});
    assert.equal(errorStub.callCount, 0);

    plugin.on(EventType.POST_REVERT, throwErrFn);
    plugin.on(EventType.POST_REVERT, getLabels);
    assert.deepEqual(element.getReviewPostRevert(undefined), {
      labels: {'Code-Review': 1},
    });
    assert.isTrue(errorStub.calledOnce);
  });

  test('postrevert event review', () => {
    function getReview(_c: unknown) {
      return {labels: {'Code-Review': 1}};
    }

    assert.deepEqual(element.getReviewPostRevert(undefined), {});
    assert.equal(errorStub.callCount, 0);

    plugin.on(EventType.POST_REVERT, throwErrFn);
    plugin.on(EventType.POST_REVERT, getReview);
    assert.deepEqual(element.getReviewPostRevert(undefined), {
      labels: {'Code-Review': 1},
    });
    assert.isTrue(errorStub.calledOnce);
  });

  test('commitmsgedit event', async () => {
    const commitMsgEditStub = stub();
    const testMsg = 'Test CL commit message';

    plugin.on(EventType.COMMIT_MSG_EDIT, throwErrFn);
    plugin.on(EventType.COMMIT_MSG_EDIT, commitMsgEditStub);
    element.handleCommitMessage(createChange(), testMsg);
    await waitUntilCalled(commitMsgEditStub, 'commitMsgEditStub');

    const msg = commitMsgEditStub.firstCall.args[1];
    assert.deepEqual(msg, testMsg);
    assert.isTrue(errorStub.calledOnce);
  });

  test('labelchange event', async () => {
    const labelChangeStub = stub();
    const testChange: ParsedChangeInfo = {
      ...createParsedChange(),
      _number: 42 as NumericChangeId,
    };

    plugin.on(EventType.LABEL_CHANGE, throwErrFn);
    plugin.on(EventType.LABEL_CHANGE, labelChangeStub);
    element.handleLabelChange({change: testChange});
    await waitUntilCalled(labelChangeStub, 'labelChangeStub');

    const [change] = labelChangeStub.firstCall.args;
    assert.deepEqual(change, testChange);
    assert.isTrue(errorStub.calledOnce);
  });

  test('submitchange', () => {
    plugin.on(EventType.SUBMIT_CHANGE, throwErrFn);
    plugin.on(EventType.SUBMIT_CHANGE, () => true);
    assert.isTrue(element.canSubmitChange(createChange()));
    assert.isTrue(errorStub.calledOnce);
    plugin.on(EventType.SUBMIT_CHANGE, () => false);
    plugin.on(EventType.SUBMIT_CHANGE, () => true);
    assert.isFalse(element.canSubmitChange(createChange()));
    assert.isTrue(errorStub.calledTwice);
  });

  test('getLoggedIn', async () => {
    // fake fetch for authCheck
    stub(window, 'fetch').resolves(new Response(undefined, {status: 204}));
    const loggedIn = await plugin.restApi().getLoggedIn();
    assert.isTrue(loggedIn);
  });

  test('getAdminMenuLinks', () => {
    const links = [
      {text: 'a', url: 'b'},
      {text: 'c', url: 'd'},
    ];
    // getAdminMenuLinks expects _getEventCallbacks to really return
    // GrAdminApi[] even though _getEventCallbacks has return type
    // EventCallback[]. Therefore this test must also return GrAdminApi[]
    // disguised as EventCallback[].
    const getCallbacksStub = stub(element, '_getEventCallbacks').returns([
      {getMenuLinks: () => [links[0]]},
      {getMenuLinks: () => [links[1]]},
    ] as unknown as EventCallback[]);
    const result = element.getAdminMenuLinks();
    assert.deepEqual(result, links);
    assert.isTrue(getCallbacksStub.calledOnce);
    assert.equal(getCallbacksStub.lastCall.args[0], EventType.ADMIN_MENU_LINKS);
  });

  suite('test plugin with base url', () => {
    let baseUrlPlugin: Plugin;

    setup(() => {
      stubBaseUrl('/r');

      pluginLoader.install(
        p => {
          // We are using the plugin API as the implementation class rather than
          // the interface to better set up tests.
          baseUrlPlugin = p as Plugin;
        },
        '0.1',
        'http://test.com/r/plugins/baseurlplugin/static/test.js'
      );
    });

    test('url', () => {
      assert.notEqual(
        baseUrlPlugin.url(),
        'http://test.com/plugins/baseurlplugin/'
      );
      assert.equal(
        baseUrlPlugin.url(),
        'http://test.com/r/plugins/baseurlplugin/'
      );
      assert.equal(
        baseUrlPlugin.url('/static/test.js'),
        'http://test.com/r/plugins/baseurlplugin/static/test.js'
      );
    });
  });

  suite('popup', () => {
    test('popup(moduleName) creates popup with component', () => {
      const openStub = stub(GrPopupInterface.prototype, 'open').callsFake(
        async function (this: GrPopupInterface) {
          // Arrow function can't be used here, because we want to
          // get properties from the instance of GrPopupInterface
          assert.equal(this.plugin, plugin);
          assert.equal(this.moduleName, 'some-name');
          return this;
        }
      );
      plugin.popup('some-name');
      assert.isTrue(openStub.calledOnce);
    });
  });

  suite('screen', () => {
    test('screenUrl()', () => {
      stubBaseUrl('/base');
      assert.equal(plugin.screenUrl(), `${location.origin}/base/x/testplugin`);
      assert.equal(
        plugin.screenUrl('foo'),
        `${location.origin}/base/x/testplugin/foo`
      );
    });

    test('works', () => {
      const registerCustomComponentStub = stub(
        plugin,
        'registerCustomComponent'
      );
      plugin.screen('foo', 'some-module');
      assert.isTrue(
        registerCustomComponentStub.calledWith(
          'testplugin-screen-foo',
          'some-module'
        )
      );
    });
  });
});
