/**
 * @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';
import {getComputedStyleValue} from '../../../utils/dom-util';
import './gr-settings-view';
import {GrSettingsView} from './gr-settings-view';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom';
import {GerritView} from '../../../services/router/router-model';
import {queryAll, queryAndAssert, stubRestApi} from '../../../test/test-utils';
import {
  AuthInfo,
  AccountDetailInfo,
  EmailAddress,
  PreferencesInfo,
  ServerInfo,
  TopMenuItemInfo,
} from '../../../types/common';
import {
  createDefaultPreferences,
  DateFormat,
  DefaultBase,
  DiffViewMode,
  EmailFormat,
  EmailStrategy,
  TimeFormat,
} from '../../../constants/constants';
import * as MockInteractions from '@polymer/iron-test-helpers/mock-interactions';
import {
  createAccountDetailWithId,
  createPreferences,
  createServerInfo,
} from '../../../test/test-data-generators';
import {GrSelect} from '../../shared/gr-select/gr-select';
import {AppElementSettingsParam} from '../../gr-app-types';

const basicFixture = fixtureFromElement('gr-settings-view');
const blankFixture = fixtureFromElement('div');

suite('gr-settings-view tests', () => {
  let element: GrSettingsView;
  let account: AccountDetailInfo;
  let preferences: PreferencesInfo;
  let config: ServerInfo;

  function valueOf(title: string, id: string) {
    const sections = element.root?.querySelectorAll(`#${id} section`) ?? [];
    let titleEl;
    for (let i = 0; i < sections.length; i++) {
      titleEl = sections[i].querySelector('.title');
      if (titleEl?.textContent?.trim() === title) {
        const el = sections[i].querySelector('.value');
        if (el) return el;
      }
    }
    assert.fail(`element with title ${title} not found`);
  }

  // Because deepEqual isn't behaving in Safari.
  function assertMenusEqual(
    actual?: TopMenuItemInfo[],
    expected?: TopMenuItemInfo[]
  ) {
    if (actual === undefined) {
      assert.fail("assertMenusEqual 'actual' param is undefined");
    } else if (expected === undefined) {
      assert.fail("assertMenusEqual 'expected' param is undefined");
    }
    assert.equal(actual.length, expected.length);
    for (let i = 0; i < actual.length; i++) {
      assert.equal(actual[i].name, expected[i].name);
      assert.equal(actual[i].url, expected[i].url);
    }
  }

  function stubAddAccountEmail(statusCode: number) {
    return stubRestApi('addAccountEmail').callsFake(() =>
      Promise.resolve({status: statusCode} as Response)
    );
  }

  setup(async () => {
    account = {
      ...createAccountDetailWithId(123),
      name: 'user name',
      email: 'user@email' as EmailAddress,
      username: 'user username',
    };
    preferences = {
      ...createPreferences(),
      changes_per_page: 25,
      date_format: DateFormat.UK,
      time_format: TimeFormat.HHMM_12,
      diff_view: DiffViewMode.UNIFIED,
      email_strategy: EmailStrategy.ENABLED,
      email_format: EmailFormat.HTML_PLAINTEXT,
      default_base_for_merges: DefaultBase.FIRST_PARENT,
      relative_date_in_change_table: false,
      size_bar_in_change_table: true,
      my: [
        {url: '/first/url', name: 'first name', target: '_blank'},
        {url: '/second/url', name: 'second name', target: '_blank'},
      ] as TopMenuItemInfo[],
      change_table: [],
    };
    config = createServerInfo();

    stubRestApi('getAccount').returns(Promise.resolve(account));
    stubRestApi('getPreferences').returns(Promise.resolve(preferences));
    stubRestApi('getAccountEmails').returns(Promise.resolve(undefined));
    stubRestApi('getConfig').returns(Promise.resolve(config));
    element = basicFixture.instantiate();

    // Allow the element to render.
    if (element._testOnly_loadingPromise)
      await element._testOnly_loadingPromise;
  });

  test('theme changing', () => {
    window.localStorage.removeItem('dark-theme');
    assert.isFalse(window.localStorage.getItem('dark-theme') === 'true');
    const themeToggle = queryAndAssert(
      element,
      '.darkToggle paper-toggle-button'
    );
    /* const themeToggle = element.shadowRoot
        .querySelector('.darkToggle paper-toggle-button'); */
    MockInteractions.tap(themeToggle);
    assert.isTrue(window.localStorage.getItem('dark-theme') === 'true');
    assert.equal(
      getComputedStyleValue('--primary-text-color', document.body),
      '#e8eaed'
    );
    MockInteractions.tap(themeToggle);
    assert.isFalse(window.localStorage.getItem('dark-theme') === 'true');
  });

  test('calls the title-change event', () => {
    const titleChangedStub = sinon.stub();

    // Create a new view.
    const newElement = document.createElement('gr-settings-view');
    newElement.addEventListener('title-change', titleChangedStub);

    const blank = blankFixture.instantiate();
    blank.appendChild(newElement);

    flush();

    assert.isTrue(titleChangedStub.called);
    assert.equal(titleChangedStub.getCall(0).args[0].detail.title, 'Settings');
  });

  test('user preferences', async () => {
    // Rendered with the expected preferences selected.
    assert.equal(
      Number(
        (
          valueOf('Changes per page', 'preferences')!
            .firstElementChild as GrSelect
        ).bindValue
      ),
      preferences.changes_per_page
    );
    assert.equal(
      (
        valueOf('Date/time format', 'preferences')!
          .firstElementChild as GrSelect
      ).bindValue,
      preferences.date_format
    );
    assert.equal(
      (valueOf('Date/time format', 'preferences')!.lastElementChild as GrSelect)
        .bindValue,
      preferences.time_format
    );
    assert.equal(
      (
        valueOf('Email notifications', 'preferences')!
          .firstElementChild as GrSelect
      ).bindValue,
      preferences.email_strategy
    );
    assert.equal(
      (valueOf('Email format', 'preferences')!.firstElementChild as GrSelect)
        .bindValue,
      preferences.email_format
    );
    assert.equal(
      (
        valueOf('Default Base For Merges', 'preferences')!
          .firstElementChild as GrSelect
      ).bindValue,
      preferences.default_base_for_merges
    );
    assert.equal(
      (
        valueOf('Show Relative Dates In Changes Table', 'preferences')!
          .firstElementChild as HTMLInputElement
      ).checked,
      false
    );
    assert.equal(
      (valueOf('Diff view', 'preferences')!.firstElementChild as GrSelect)
        .bindValue,
      preferences.diff_view
    );
    assert.equal(
      (
        valueOf('Show size bars in file list', 'preferences')!
          .firstElementChild as HTMLInputElement
      ).checked,
      true
    );
    assert.equal(
      (
        valueOf('Publish comments on push', 'preferences')!
          .firstElementChild as HTMLInputElement
      ).checked,
      false
    );
    assert.equal(
      (
        valueOf(
          'Set new changes to "work in progress" by default',
          'preferences'
        )!.firstElementChild as HTMLInputElement
      ).checked,
      false
    );
    assert.equal(
      (
        valueOf(
          'Insert Signed-off-by Footer For Inline Edit Changes',
          'preferences'
        )!.firstElementChild as HTMLInputElement
      ).checked,
      false
    );

    assert.isFalse(element._prefsChanged);
    assert.isFalse(element._menuChanged);

    const publishOnPush = valueOf('Publish comments on push', 'preferences')!
      .firstElementChild!;

    MockInteractions.tap(publishOnPush);

    assert.isTrue(element._prefsChanged);
    assert.isFalse(element._menuChanged);

    stubRestApi('savePreferences').callsFake(prefs => {
      assertMenusEqual(prefs.my, preferences.my);
      assert.equal(prefs.publish_comments_on_push, true);
      return Promise.resolve(new Response());
    });

    // Save the change.
    await element._handleSavePreferences();
    assert.isFalse(element._prefsChanged);
    assert.isFalse(element._menuChanged);
  });

  test('publish comments on push', async () => {
    const publishCommentsOnPush = valueOf(
      'Publish comments on push',
      'preferences'
    )!.firstElementChild!;
    MockInteractions.tap(publishCommentsOnPush);

    assert.isFalse(element._menuChanged);
    assert.isTrue(element._prefsChanged);

    stubRestApi('savePreferences').callsFake(prefs => {
      assert.equal(prefs.publish_comments_on_push, true);
      return Promise.resolve(new Response());
    });

    // Save the change.
    await element._handleSavePreferences();
    assert.isFalse(element._prefsChanged);
    assert.isFalse(element._menuChanged);
  });

  test('set new changes work-in-progress', async () => {
    const newChangesWorkInProgress = valueOf(
      'Set new changes to "work in progress" by default',
      'preferences'
    )!.firstElementChild!;
    MockInteractions.tap(newChangesWorkInProgress);

    assert.isFalse(element._menuChanged);
    assert.isTrue(element._prefsChanged);

    stubRestApi('savePreferences').callsFake(prefs => {
      assert.equal(prefs.work_in_progress_by_default, true);
      return Promise.resolve(new Response());
    });

    // Save the change.
    await element._handleSavePreferences();
    assert.isFalse(element._prefsChanged);
    assert.isFalse(element._menuChanged);
  });

  test('menu', async () => {
    assert.isFalse(element._menuChanged);
    assert.isFalse(element._prefsChanged);

    assertMenusEqual(element._localMenu, preferences.my);

    const menu = element.$.menu.firstElementChild!;
    let tableRows = queryAll(menu, 'tbody tr');
    // let tableRows = menu.root.querySelectorAll('tbody tr');
    assert.equal(tableRows.length, preferences.my.length);

    // Add a menu item:
    element.splice('_localMenu', 1, 0, {name: 'foo', url: 'bar', target: ''});
    flush();

    // tableRows = menu.root.querySelectorAll('tbody tr');
    tableRows = queryAll(menu, 'tbody tr');
    assert.equal(tableRows.length, preferences.my.length + 1);

    assert.isTrue(element._menuChanged);
    assert.isFalse(element._prefsChanged);

    stubRestApi('savePreferences').callsFake(prefs => {
      assertMenusEqual(prefs.my, element._localMenu);
      return Promise.resolve(new Response());
    });

    await element._handleSaveMenu();
    assert.isFalse(element._menuChanged);
    assert.isFalse(element._prefsChanged);
    assertMenusEqual(element.prefs.my, element._localMenu);
  });

  test('add email validation', () => {
    assert.isFalse(element._isNewEmailValid('invalid email'));
    assert.isTrue(element._isNewEmailValid('vaguely@valid.email'));

    assert.isFalse(
      element._computeAddEmailButtonEnabled('invalid email', true)
    );
    assert.isFalse(
      element._computeAddEmailButtonEnabled('vaguely@valid.email', true)
    );
    assert.isTrue(
      element._computeAddEmailButtonEnabled('vaguely@valid.email', false)
    );
  });

  test('add email does not save invalid', () => {
    const addEmailStub = stubAddAccountEmail(201);

    assert.isFalse(element._addingEmail);
    assert.isNotOk(element._lastSentVerificationEmail);
    element._newEmail = 'invalid email';

    element._handleAddEmailButton();

    assert.isFalse(element._addingEmail);
    assert.isFalse(addEmailStub.called);
    assert.isNotOk(element._lastSentVerificationEmail);

    assert.isFalse(addEmailStub.called);
  });

  test('add email does save valid', async () => {
    const addEmailStub = stubAddAccountEmail(201);

    assert.isFalse(element._addingEmail);
    assert.isNotOk(element._lastSentVerificationEmail);
    element._newEmail = 'valid@email.com';

    element._handleAddEmailButton();

    assert.isTrue(element._addingEmail);
    assert.isTrue(addEmailStub.called);

    assert.isTrue(addEmailStub.called);
    await addEmailStub.lastCall.returnValue;
    assert.isOk(element._lastSentVerificationEmail);
  });

  test('add email does not set last-email if error', async () => {
    const addEmailStub = stubAddAccountEmail(500);

    assert.isNotOk(element._lastSentVerificationEmail);
    element._newEmail = 'valid@email.com';

    element._handleAddEmailButton();

    assert.isTrue(addEmailStub.called);
    await addEmailStub.lastCall.returnValue;
    assert.isNotOk(element._lastSentVerificationEmail);
  });

  test('emails are loaded without emailToken', () => {
    const emailEditorLoadDataStub = sinon.stub(
      element.$.emailEditor,
      'loadData'
    );
    element.params = {
      view: GerritView.SETTINGS,
    } as AppElementSettingsParam;
    element.connectedCallback();
    assert.isTrue(emailEditorLoadDataStub.calledOnce);
  });

  test('_handleSaveChangeTable', () => {
    let newColumns = ['Owner', 'Project', 'Branch'];
    element._localChangeTableColumns = newColumns.slice(0);
    element._showNumber = false;
    element._handleSaveChangeTable();
    assert.deepEqual(element.prefs.change_table, newColumns);
    assert.isNotOk(element.prefs.legacycid_in_change_table);

    newColumns = ['Size'];
    element._localChangeTableColumns = newColumns;
    element._showNumber = true;
    element._handleSaveChangeTable();
    assert.deepEqual(element.prefs.change_table, newColumns);
    assert.isTrue(element.prefs.legacycid_in_change_table);
  });

  test('reset menu item back to default', async () => {
    const originalMenu = {
      ...createDefaultPreferences(),
      my: [
        {url: '/first/url', name: 'first name', target: '_blank'},
        {url: '/second/url', name: 'second name', target: '_blank'},
        {url: '/third/url', name: 'third name', target: '_blank'},
      ] as TopMenuItemInfo[],
    };

    stubRestApi('getDefaultPreferences').returns(Promise.resolve(originalMenu));

    const updatedMenu = [
      {url: '/first/url', name: 'first name', target: '_blank'},
      {url: '/second/url', name: 'second name', target: '_blank'},
      {url: '/third/url', name: 'third name', target: '_blank'},
      {url: '/fourth/url', name: 'fourth name', target: '_blank'},
    ];

    element.set('_localMenu', updatedMenu);

    await element._handleResetMenuButton();
    assertMenusEqual(element._localMenu, originalMenu.my);
  });

  test('test that reset button is called', () => {
    const overlayOpen = sinon.stub(element, '_handleResetMenuButton');

    MockInteractions.tap(element.$.resetButton);

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

  test('_showHttpAuth', () => {
    const serverConfig: ServerInfo = {
      ...createServerInfo(),
      auth: {
        git_basic_auth_policy: 'HTTP',
      } as AuthInfo,
    };

    assert.isTrue(element._showHttpAuth(serverConfig));

    serverConfig.auth.git_basic_auth_policy = 'HTTP_LDAP';
    assert.isTrue(element._showHttpAuth(serverConfig));

    serverConfig.auth.git_basic_auth_policy = 'LDAP';
    assert.isFalse(element._showHttpAuth(serverConfig));

    serverConfig.auth.git_basic_auth_policy = 'OAUTH';
    assert.isFalse(element._showHttpAuth(serverConfig));

    assert.isFalse(element._showHttpAuth(undefined));
  });

  suite('_getFilterDocsLink', () => {
    test('with http: docs base URL', () => {
      const base = 'http://example.com/';
      const result = element._getFilterDocsLink(base);
      assert.equal(result, 'http://example.com/user-notify.html');
    });

    test('with http: docs base URL without slash', () => {
      const base = 'http://example.com';
      const result = element._getFilterDocsLink(base);
      assert.equal(result, 'http://example.com/user-notify.html');
    });

    test('with https: docs base URL', () => {
      const base = 'https://example.com/';
      const result = element._getFilterDocsLink(base);
      assert.equal(result, 'https://example.com/user-notify.html');
    });

    test('without docs base URL', () => {
      const result = element._getFilterDocsLink(null);
      assert.equal(
        result,
        'https://gerrit-review.googlesource.com/' +
          'Documentation/user-notify.html'
      );
    });

    test('ignores non HTTP links', () => {
      const base = 'javascript://alert("evil");';
      const result = element._getFilterDocsLink(base);
      assert.equal(
        result,
        'https://gerrit-review.googlesource.com/' +
          'Documentation/user-notify.html'
      );
    });
  });

  suite('when email verification token is provided', () => {
    let resolveConfirm: (
      value: string | PromiseLike<string | null> | null
    ) => void;
    let confirmEmailStub: sinon.SinonStub;
    let emailEditorLoadDataStub: sinon.SinonStub;

    setup(() => {
      emailEditorLoadDataStub = sinon.stub(element.$.emailEditor, 'loadData');
      confirmEmailStub = stubRestApi('confirmEmail').returns(
        new Promise(resolve => {
          resolveConfirm = resolve;
        })
      );

      element.params = {view: GerritView.SETTINGS, emailToken: 'foo'};
      element.connectedCallback();
    });

    test('it is used to confirm email via rest API', () => {
      assert.isTrue(confirmEmailStub.calledOnce);
      assert.isTrue(confirmEmailStub.calledWith('foo'));
    });

    test('emails are not loaded initially', () => {
      assert.isFalse(emailEditorLoadDataStub.called);
    });

    test('user emails are loaded after email confirmed', async () => {
      resolveConfirm('bar');
      await element._testOnly_loadingPromise;
      assert.isTrue(emailEditorLoadDataStub.calledOnce);
    });

    test('show-alert is fired when email is confirmed', async () => {
      const dispatchEventSpy = sinon.spy(element, 'dispatchEvent');
      resolveConfirm('bar');

      await element._testOnly_loadingPromise;
      assert.equal(
        (dispatchEventSpy.lastCall.args[0] as CustomEvent).type,
        'show-alert'
      );
      assert.deepEqual(
        (dispatchEventSpy.lastCall.args[0] as CustomEvent).detail,
        {message: 'bar'}
      );
    });
  });
});
