/**
 * @license
 * Copyright (C) 2019 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 '../../elements/shared/gr-rest-api-interface/gr-rest-api-interface.js';
import {GrDisplayNameUtils} from '../gr-display-name-utils/gr-display-name-utils.js';
import {GrReviewerSuggestionsProvider, SUGGESTIONS_PROVIDERS_USERS_TYPES} from './gr-reviewer-suggestions-provider.js';
import {html} from '@polymer/polymer/lib/utils/html-tag.js';

const basicFixture = fixtureFromTemplate(html`
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
`);

suite('GrReviewerSuggestionsProvider tests', () => {
  let _nextAccountId = 0;
  const makeAccount = function(opt_status) {
    const accountId = ++_nextAccountId;
    return {
      _account_id: accountId,
      name: 'name ' + accountId,
      email: 'email ' + accountId,
      status: opt_status,
    };
  };
  let _nextAccountId2 = 0;
  const makeAccount2 = function(opt_status) {
    const accountId2 = ++_nextAccountId2;
    return {
      _account_id: accountId2,
      name: 'name ' + accountId2,
      status: opt_status,
    };
  };

  let owner;
  let existingReviewer1;
  let existingReviewer2;
  let suggestion1;
  let suggestion2;
  let suggestion3;
  let restAPI;
  let provider;

  let redundantSuggestion1;
  let redundantSuggestion2;
  let redundantSuggestion3;
  let change;

  setup(done => {
    owner = makeAccount();
    existingReviewer1 = makeAccount();
    existingReviewer2 = makeAccount();
    suggestion1 = {account: makeAccount()};
    suggestion2 = {account: makeAccount()};
    suggestion3 = {
      group: {
        id: 'suggested group id',
        name: 'suggested group',
      },
    };

    stub('gr-rest-api-interface', {
      getLoggedIn() { return Promise.resolve(true); },
      getConfig() { return Promise.resolve({}); },
    });

    restAPI = basicFixture.instantiate();
    change = {
      _number: 42,
      owner,
      reviewers: {
        CC: [existingReviewer1],
        REVIEWER: [existingReviewer2],
      },
    };

    return flush(done);
  });

  suite('allowAnyUser set to false', () => {
    setup(done => {
      provider = GrReviewerSuggestionsProvider.create(restAPI, change._number,
          SUGGESTIONS_PROVIDERS_USERS_TYPES.REVIEWER);
      provider.init().then(done);
    });
    suite('stubbed values for _getReviewerSuggestions', () => {
      setup(() => {
        stub('gr-rest-api-interface', {
          getChangeSuggestedReviewers() {
            redundantSuggestion1 = {account: existingReviewer1};
            redundantSuggestion2 = {account: existingReviewer2};
            redundantSuggestion3 = {account: owner};
            return Promise.resolve([redundantSuggestion1, redundantSuggestion2,
              redundantSuggestion3, suggestion1, suggestion2, suggestion3]);
          },
        });
      });

      test('makeSuggestionItem formats account or group accordingly', () => {
        let account = makeAccount();
        const account3 = makeAccount2();
        let suggestion = provider.makeSuggestionItem({account});
        assert.deepEqual(suggestion, {
          name: account.name + ' <' + account.email + '>',
          value: {account},
        });

        const group = {name: 'test'};
        suggestion = provider.makeSuggestionItem({group});
        assert.deepEqual(suggestion, {
          name: group.name + ' (group)',
          value: {group},
        });

        suggestion = provider.makeSuggestionItem(account);
        assert.deepEqual(suggestion, {
          name: account.name + ' <' + account.email + '>',
          value: {account, count: 1},
        });

        suggestion = provider.makeSuggestionItem({account: {}});
        assert.deepEqual(suggestion, {
          name: 'Anonymous',
          value: {account: {}},
        });

        provider._config = {
          user: {
            anonymous_coward_name: 'Anonymous Coward Name',
          },
        };

        suggestion = provider.makeSuggestionItem({account: {}});
        assert.deepEqual(suggestion, {
          name: 'Anonymous Coward Name',
          value: {account: {}},
        });

        account = makeAccount('OOO');

        suggestion = provider.makeSuggestionItem({account});
        assert.deepEqual(suggestion, {
          name: account.name + ' <' + account.email + '> (OOO)',
          value: {account},
        });

        suggestion = provider.makeSuggestionItem(account);
        assert.deepEqual(suggestion, {
          name: account.name + ' <' + account.email + '> (OOO)',
          value: {account, count: 1},
        });

        sinon.stub(GrDisplayNameUtils, '_accountEmail').callsFake(
            () => '');

        suggestion = provider.makeSuggestionItem(account3);
        assert.deepEqual(suggestion, {
          name: account3.name,
          value: {account: account3, count: 1},
        });
      });

      test('getSuggestions', done => {
        provider.getSuggestions()
            .then(reviewers => {
              // Default is no filtering.
              assert.equal(reviewers.length, 6);
              assert.deepEqual(reviewers,
                  [redundantSuggestion1, redundantSuggestion2,
                    redundantSuggestion3, suggestion1,
                    suggestion2, suggestion3]);
            })
            .then(done);
      });

      test('getSuggestions short circuits when logged out', () => {
        // API call is already stubbed.
        const xhrSpy = restAPI.getChangeSuggestedReviewers;
        provider._loggedIn = false;
        return provider.getSuggestions('').then(() => {
          assert.isFalse(xhrSpy.called);
          provider._loggedIn = true;
          return provider.getSuggestions('').then(() => {
            assert.isTrue(xhrSpy.called);
          });
        });
      });
    });

    test('getChangeSuggestedReviewers is used', done => {
      const suggestReviewerStub =
          sinon.stub(restAPI, 'getChangeSuggestedReviewers')
              .returns(Promise.resolve([]));
      const suggestAccountStub =
          sinon.stub(restAPI, 'getSuggestedAccounts')
              .returns(Promise.resolve([]));

      provider.getSuggestions('').then(() => {
        assert.isTrue(suggestReviewerStub.calledOnce);
        assert.isTrue(suggestReviewerStub.calledWith(42, ''));
        assert.isFalse(suggestAccountStub.called);
        done();
      });
    });
  });

  suite('allowAnyUser set to true', () => {
    setup(done => {
      provider = GrReviewerSuggestionsProvider.create(restAPI, change._number,
          SUGGESTIONS_PROVIDERS_USERS_TYPES.ANY);
      provider.init().then(done);
    });

    test('getSuggestedAccounts is used', done => {
      const suggestReviewerStub =
          sinon.stub(restAPI, 'getChangeSuggestedReviewers')
              .returns(Promise.resolve([]));
      const suggestAccountStub =
          sinon.stub(restAPI, 'getSuggestedAccounts')
              .returns(Promise.resolve([]));

      provider.getSuggestions('').then(() => {
        assert.isFalse(suggestReviewerStub.called);
        assert.isTrue(suggestAccountStub.calledOnce);
        assert.isTrue(suggestAccountStub.calledWith('cansee:42 '));
        done();
      });
    });
  });
});

