/**
 * @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 pluginLoader: PluginLoader;

  let clock: SinonFakeTimers;

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

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

    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([]);
  });

  teardown(() => {
    clock.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'
        )
      );
    });
  });
});
