/**
 * @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 {
  stubRestApi,
  stubBaseUrl,
  waitEventLoop,
  waitUntilCalled,
  assertFails,
} 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 {useFakeTimers, stub, SinonFakeTimers, SinonStub} from 'sinon';
import {GrJsApiInterface} from './gr-js-api-interface-element';
import {Plugin} from './gr-public-js-api';
import {
  ChangeInfo,
  HttpMethod,
  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';

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

  let sendStub: SinonStub;
  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,
    });
    sendStub = stubRestApi('send').resolves(
      new Response(undefined, {status: 200})
    );
    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('_send on failure rejects with response text', async () => {
    sendStub.resolves({
      status: 400,
      text() {
        return Promise.resolve('text');
      },
    });
    const error = await assertFails<Error>(plugin._send(HttpMethod.POST, ''));
    assert.equal(error.message, 'text');
  });

  test('_send on failure without text rejects with code', async () => {
    sendStub.resolves({
      status: 400,
      text() {
        return Promise.resolve(null);
      },
    });
    const error = await assertFails<Error>(plugin._send(HttpMethod.POST, ''));
    assert.equal(error.message, '400');
  });

  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('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('attributeHelper', () => {
    assert.isOk(plugin.attributeHelper(document.createElement('div')));
  });

  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'
        )
      );
    });
  });
});
