/**
 * @license
 * Copyright (C) 2016 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 '../../../test/common-test-setup-karma.js';
import './gr-error-manager.js';
import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
import {__testOnly_ErrorType} from './gr-error-manager.js';
import {stubRestApi} from '../../../test/test-utils.js';
import {appContext} from '../../../services/app-context.js';

const basicFixture = fixtureFromElement('gr-error-manager');

_testOnly_initGerritPluginApi();

suite('gr-error-manager tests', () => {
  let element;

  suite('when authed', () => {
    let toastSpy;
    let openOverlaySpy;
    let fetchStub;
    let getLoggedInStub;

    setup(() => {
      fetchStub = sinon.stub(window, 'fetch')
          .returns(Promise.resolve({ok: true, status: 204}));
      getLoggedInStub = stubRestApi('getLoggedIn')
          .callsFake(() => appContext.authService.authCheck());
      element = basicFixture.instantiate();
      element._authService.clearCache();
      toastSpy = sinon.spy(element, '_createToastAlert');
      openOverlaySpy = sinon.spy(element.$.noInteractionOverlay, 'open');
    });

    teardown(() => {
      toastSpy.getCalls().forEach(call => {
        call.returnValue.remove();
      });
    });

    test('does not show auth error on 403 by default', done => {
      const showAuthErrorStub = sinon.stub(element, '_showAuthErrorAlert');
      const responseText = Promise.resolve('server says no.');
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail:
          {response: {status: 403, text() { return responseText; }}},
            composed: true, bubbles: true,
          }));
      flush(() => {
        assert.isFalse(showAuthErrorStub.calledOnce);
        done();
      });
    });

    test('show auth required for 403 with auth error and not authed before',
        done => {
          const showAuthErrorStub = sinon.stub(
              element, '_showAuthErrorAlert'
          );
          const responseText = Promise.resolve('Authentication required\n');
          getLoggedInStub.returns(Promise.resolve(true));
          element.dispatchEvent(
              new CustomEvent('server-error', {
                detail:
              {response: {status: 403, text() { return responseText; }}},
                composed: true, bubbles: true,
              }));
          flush(() => {
            assert.isTrue(showAuthErrorStub.calledOnce);
            done();
          });
        });

    test('recheck auth for 403 with auth error if authed before', async () => {
      // Set status to AUTHED.
      appContext.authService.authCheck();
      const responseText = Promise.resolve('Authentication required\n');
      getLoggedInStub.returns(Promise.resolve(true));
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail:
          {response: {status: 403, text() { return responseText; }}},
            composed: true, bubbles: true,
          }));
      await flush();
      assert.isTrue(getLoggedInStub.calledOnce);
    });

    test('show logged in error', () => {
      const spy = sinon.spy(element, '_showAuthErrorAlert');
      element.dispatchEvent(
          new CustomEvent('show-auth-required', {
            composed: true, bubbles: true,
          }));
      assert.isTrue(spy.calledWithExactly(
          'Log in is required to perform that action.', 'Log in.'));
    });

    test('show normal Error', done => {
      const showErrorSpy = sinon.spy(element, '_showErrorDialog');
      const textSpy = sinon.spy(() => Promise.resolve('ZOMG'));
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail: {response: {status: 500, text: textSpy}},
            composed: true, bubbles: true,
          }));

      assert.isTrue(textSpy.called);
      flush(() => {
        assert.isTrue(showErrorSpy.calledOnce);
        assert.isTrue(showErrorSpy.lastCall.calledWithExactly(
            'Error 500: ZOMG'));
        done();
      });
    });

    test('_constructServerErrorMsg', () => {
      const errorText = 'change conflicts';
      const status = 409;
      const statusText = 'Conflict';
      const url = '/my/test/url';

      assert.equal(element._constructServerErrorMsg({status}),
          'Error 409');
      assert.equal(element._constructServerErrorMsg({status, url}),
          'Error 409: \nEndpoint: /my/test/url');
      assert.equal(element.
          _constructServerErrorMsg({status, statusText, url}),
      'Error 409 (Conflict): \nEndpoint: /my/test/url');
      assert.equal(element._constructServerErrorMsg({
        status,
        statusText,
        errorText,
        url,
      }), 'Error 409 (Conflict): change conflicts' +
      '\nEndpoint: /my/test/url');
      assert.equal(element._constructServerErrorMsg({
        status,
        statusText,
        errorText,
        url,
        trace: 'xxxxx',
      }), 'Error 409 (Conflict): change conflicts' +
      '\nEndpoint: /my/test/url\nTrace Id: xxxxx');
    });

    test('extract trace id from headers if exists', done => {
      const textSpy = sinon.spy(
          () => Promise.resolve('500')
      );
      const headers = new Headers();
      headers.set('X-Gerrit-Trace', 'xxxx');
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail: {
              response: {
                headers,
                status: 500,
                text: textSpy,
              },
            },
            composed: true, bubbles: true,
          }));
      flush(() => {
        assert.equal(
            element.$.errorDialog.text,
            'Error 500: 500\nTrace Id: xxxx'
        );
        done();
      });
    });

    test('suppress TOO_MANY_FILES error', done => {
      const showAlertStub = sinon.stub(element, '_showAlert');
      const textSpy = sinon.spy(
          () => Promise.resolve('too many files to find conflicts')
      );
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail: {response: {status: 500, text: textSpy}},
            composed: true, bubbles: true,
          }));

      assert.isTrue(textSpy.called);
      flush(() => {
        assert.isFalse(showAlertStub.called);
        done();
      });
    });

    test('show network error', done => {
      const consoleErrorStub = sinon.stub(console, 'error');
      const showAlertStub = sinon.stub(element, '_showAlert');
      element.dispatchEvent(
          new CustomEvent('network-error', {
            detail: {error: new Error('ZOMG')},
            composed: true, bubbles: true,
          }));
      flush(() => {
        assert.isTrue(showAlertStub.calledOnce);
        assert.isTrue(showAlertStub.lastCall.calledWithExactly(
            'Server unavailable'));
        assert.isTrue(consoleErrorStub.calledOnce);
        assert.isTrue(consoleErrorStub.lastCall.calledWithExactly('ZOMG'));
        done();
      });
    });

    test('_canOverride alerts', () => {
      assert.isFalse(element._canOverride(undefined,
          __testOnly_ErrorType.AUTH));
      assert.isFalse(element._canOverride(undefined,
          __testOnly_ErrorType.NETWORK));
      assert.isTrue(element._canOverride(undefined,
          __testOnly_ErrorType.GENERIC));
      assert.isTrue(element._canOverride(undefined, undefined));

      assert.isTrue(element._canOverride(__testOnly_ErrorType.NETWORK,
          undefined));
      assert.isTrue(element._canOverride(__testOnly_ErrorType.AUTH,
          undefined));
      assert.isFalse(element._canOverride(__testOnly_ErrorType.NETWORK,
          __testOnly_ErrorType.AUTH));

      assert.isTrue(element._canOverride(__testOnly_ErrorType.AUTH,
          __testOnly_ErrorType.NETWORK));
    });

    test('show auth refresh toast', async () => {
      // Set status to AUTHED.
      appContext.authService.authCheck();
      const refreshStub = stubRestApi(
          'getAccount').callsFake(
          () => Promise.resolve({}));
      const windowOpen = sinon.stub(window, 'open');
      const responseText = Promise.resolve('Authentication required\n');
      // fake failed auth
      fetchStub.returns(Promise.resolve({status: 403}));
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail:
          {response: {status: 403, text() { return responseText; }}},
            composed: true, bubbles: true,
          }));
      assert.equal(fetchStub.callCount, 1);
      await flush();

      // here needs two flush as there are two chanined
      // promises on server-error handler and flush only flushes one
      assert.equal(fetchStub.callCount, 2);
      await flush();
      // Sometime overlay opens with delay, waiting while open is complete
      await openOverlaySpy.lastCall.returnValue;
      // auth-error fired
      assert.isTrue(toastSpy.called);

      // toast
      let toast = toastSpy.lastCall.returnValue;
      assert.isOk(toast);
      assert.include(
          toast.root.textContent, 'Credentials expired.');
      assert.include(
          toast.root.textContent, 'Refresh credentials');

      // noInteractionOverlay
      const noInteractionOverlay = element.$.noInteractionOverlay;
      assert.isOk(noInteractionOverlay);
      sinon.spy(noInteractionOverlay, 'close');
      assert.equal(
          noInteractionOverlay.backdropElement.getAttribute('opened'),
          '');
      assert.isFalse(windowOpen.called);
      MockInteractions.tap(toast.shadowRoot
          .querySelector('gr-button.action'));
      assert.isTrue(windowOpen.called);

      // @see Issue 5822: noopener breaks closeAfterLogin
      assert.equal(windowOpen.lastCall.args[2].indexOf('noopener=yes'),
          -1);

      const hideToastSpy = sinon.spy(toast, 'hide');

      // now fake authed
      fetchStub.returns(Promise.resolve({status: 204}));
      element.handleWindowFocus();
      element.checkLoggedInTask.flush();
      await flush();
      assert.isTrue(refreshStub.called);
      assert.isTrue(hideToastSpy.called);

      // toast update
      assert.notStrictEqual(toastSpy.lastCall.returnValue, toast);
      toast = toastSpy.lastCall.returnValue;
      assert.isOk(toast);
      assert.include(
          toast.root.textContent, 'Credentials refreshed');

      // close overlay
      assert.isTrue(noInteractionOverlay.close.called);
    });

    test('auth toast should dismiss existing toast', async () => {
      // Set status to AUTHED.
      appContext.authService.authCheck();
      const responseText = Promise.resolve('Authentication required\n');

      // fake an alert
      element.dispatchEvent(
          new CustomEvent('show-alert', {
            detail: {message: 'test reload', action: 'reload'},
            composed: true, bubbles: true,
          }));
      let toast = toastSpy.lastCall.returnValue;
      assert.isOk(toast);
      assert.include(
          toast.root.textContent, 'test reload');

      // fake auth
      fetchStub.returns(Promise.resolve({status: 403}));
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail:
          {response: {status: 403, text() { return responseText; }}},
            composed: true, bubbles: true,
          }));
      assert.equal(fetchStub.callCount, 1);
      await flush();
      // here needs two flush as there are two chained
      // promises on server-error handler and flush only flushes one
      assert.equal(fetchStub.callCount, 2);
      await flush();
      // Sometime overlay opens with delay, waiting while open is complete
      await openOverlaySpy.lastCall.returnValue;
      // toast
      toast = toastSpy.lastCall.returnValue;
      assert.include(
          toast.root.textContent, 'Credentials expired.');
      assert.include(
          toast.root.textContent, 'Refresh credentials');
    });

    test('regular toast should dismiss regular toast', () => {
      // Set status to AUTHED.
      appContext.authService.authCheck();

      // fake an alert
      element.dispatchEvent(
          new CustomEvent('show-alert', {
            detail: {message: 'test reload', action: 'reload'},
            composed: true, bubbles: true,
          }));
      let toast = toastSpy.lastCall.returnValue;
      assert.isOk(toast);
      assert.include(
          toast.root.textContent, 'test reload');

      // new alert
      element.dispatchEvent(
          new CustomEvent('show-alert', {
            detail: {message: 'second-test', action: 'reload'},
            composed: true, bubbles: true,
          }));

      toast = toastSpy.lastCall.returnValue;
      assert.include(toast.root.textContent, 'second-test');
    });

    test('regular toast should not dismiss auth toast', done => {
      // Set status to AUTHED.
      appContext.authService.authCheck();
      const responseText = Promise.resolve('Authentication required\n');

      // fake auth
      fetchStub.returns(Promise.resolve({status: 403}));
      element.dispatchEvent(
          new CustomEvent('server-error', {
            detail:
          {response: {status: 403, text() { return responseText; }}},
            composed: true, bubbles: true,
          }));
      assert.equal(fetchStub.callCount, 1);
      flush(() => {
        // here needs two flush as there are two chained
        // promises on server-error handler and flush only flushes one
        assert.equal(fetchStub.callCount, 2);
        flush(() => {
          let toast = toastSpy.lastCall.returnValue;
          assert.include(
              toast.root.textContent, 'Credentials expired.');
          assert.include(
              toast.root.textContent, 'Refresh credentials');

          // fake an alert
          element.dispatchEvent(
              new CustomEvent('show-alert', {
                detail: {
                  message: 'test-alert', action: 'reload',
                },
                composed: true, bubbles: true,
              }));
          flush(() => {
            toast = toastSpy.lastCall.returnValue;
            assert.isOk(toast);
            assert.include(
                toast.root.textContent, 'Credentials expired.');
            done();
          });
        });
      });
    });

    test('show alert', () => {
      const alertObj = {message: 'foo'};
      sinon.stub(element, '_showAlert');
      element.dispatchEvent(
          new CustomEvent('show-alert', {
            detail: alertObj,
            composed: true, bubbles: true,
          }));
      assert.isTrue(element._showAlert.calledOnce);
      assert.equal(element._showAlert.lastCall.args[0], 'foo');
      assert.isNotOk(element._showAlert.lastCall.args[1]);
      assert.isNotOk(element._showAlert.lastCall.args[2]);
    });

    test('checks stale credentials on visibility change', () => {
      const refreshStub = sinon.stub(element,
          '_checkSignedIn');
      sinon.stub(Date, 'now').returns(999999);
      element._lastCredentialCheck = 0;
      element.handleVisibilityChange();

      // Since there is no known account, it should not test credentials.
      assert.isFalse(refreshStub.called);
      assert.equal(element._lastCredentialCheck, 0);

      element.knownAccountId = 123;
      element.handleVisibilityChange();

      // Should test credentials, since there is a known account.
      assert.isTrue(refreshStub.called);
      assert.equal(element._lastCredentialCheck, 999999);
    });

    test('refreshes with same credentials', done => {
      const accountPromise = Promise.resolve({_account_id: 1234});
      stubRestApi('getAccount')
          .returns(accountPromise);
      const requestCheckStub = sinon.stub(element, '_requestCheckLoggedIn');
      const handleRefreshStub = sinon.stub(element,
          'handleCredentialRefreshed');
      const reloadStub = sinon.stub(element, '_reloadPage');

      element.knownAccountId = 1234;
      element._refreshingCredentials = true;
      element._checkSignedIn();

      flush(() => {
        assert.isFalse(requestCheckStub.called);
        assert.isTrue(handleRefreshStub.called);
        assert.isFalse(reloadStub.called);
        done();
      });
    });

    test('_showAlert hides existing alerts', () => {
      element._alertElement = element._createToastAlert();
      const hideStub = sinon.stub(element, 'hideAlert');
      element._showAlert();
      assert.isTrue(hideStub.calledOnce);
    });

    test('show-error', () => {
      const openStub = sinon.stub(element.$.errorOverlay, 'open');
      const closeStub = sinon.stub(element.$.errorOverlay, 'close');
      const reportStub = sinon.stub(
          element.reporting,
          'reportErrorDialog'
      );

      const message = 'test message';
      element.dispatchEvent(
          new CustomEvent('show-error', {
            detail: {message},
            composed: true, bubbles: true,
          }));
      flush();

      assert.isTrue(openStub.called);
      assert.isTrue(reportStub.called);
      assert.equal(element.$.errorDialog.text, message);

      element.$.errorDialog.dispatchEvent(
          new CustomEvent('dismiss', {
            composed: true, bubbles: true,
          }));
      flush();

      assert.isTrue(closeStub.called);
    });

    test('reloads when refreshed credentials differ', done => {
      const accountPromise = Promise.resolve({_account_id: 1234});
      stubRestApi('getAccount')
          .returns(accountPromise);
      const requestCheckStub = sinon.stub(
          element,
          '_requestCheckLoggedIn');
      const handleRefreshStub = sinon.stub(element,
          'handleCredentialRefreshed');
      const reloadStub = sinon.stub(element, '_reloadPage');

      element.knownAccountId = 4321; // Different from 1234
      element._refreshingCredentials = true;
      element._checkSignedIn();

      flush(() => {
        assert.isFalse(requestCheckStub.called);
        assert.isFalse(handleRefreshStub.called);
        assert.isTrue(reloadStub.called);
        done();
      });
    });
  });

  suite('when not authed', () => {
    let toastSpy;
    setup(() => {
      stubRestApi('getLoggedIn').returns(Promise.resolve(false));
      element = basicFixture.instantiate();
      toastSpy = sinon.spy(element, '_createToastAlert');
    });

    teardown(() => {
      toastSpy.getCalls().forEach(call => {
        call.returnValue.remove();
      });
    });

    test('refresh loop continues on credential fail', done => {
      const requestCheckStub = sinon.stub(
          element,
          '_requestCheckLoggedIn');
      const handleRefreshStub = sinon.stub(element,
          'handleCredentialRefreshed');
      const reloadStub = sinon.stub(element, '_reloadPage');

      element._refreshingCredentials = true;
      element._checkSignedIn();

      flush(() => {
        assert.isTrue(requestCheckStub.called);
        assert.isFalse(handleRefreshStub.called);
        assert.isFalse(reloadStub.called);
        done();
      });
    });
  });
});

