/**
 * @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';
import {createPreferences} from '../../../test/test-data-generators.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());
      stubRestApi('getPreferences').returns(Promise.resolve(
          createPreferences()));
      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();
      });
    });
  });
});

