/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../test/common-test-setup';
import './checks-model';
import {ChecksModel, ChecksPatchset, ChecksProviderState} from './checks-model';
import {
  Action,
  Category,
  CheckRun,
  ChecksApiConfig,
  ChecksProvider,
  ResponseCode,
  RunStatus,
} from '../../api/checks';
import {getAppContext} from '../../services/app-context';
import {createParsedChange} from '../../test/test-data-generators';
import {waitUntil, waitUntilCalled} from '../../test/test-utils';
import {ParsedChangeInfo} from '../../types/types';
import {changeModelToken} from '../change/change-model';
import {assert} from '@open-wc/testing';
import {testResolver} from '../../test/common-test-setup';
import {changeViewModelToken} from '../views/change';
import {NumericChangeId, PatchSetNumber} from '../../api/rest-api';
import {pluginLoaderToken} from '../../elements/shared/gr-js-api-interface/gr-plugin-loader';

const PLUGIN_NAME = 'test-plugin';

const RUNS: CheckRun[] = [
  {
    checkName: 'MacCheck',
    change: 123,
    patchset: 1,
    attempt: 1,
    status: RunStatus.COMPLETED,
    results: [
      {
        externalId: 'id-314',
        category: Category.WARNING,
        summary: 'Meddle cheddle check and you are weg.',
      },
    ],
  },
];

const CONFIG_POLLING_5S: ChecksApiConfig = {
  fetchPollingIntervalSeconds: 5,
};

const CONFIG_POLLING_NONE: ChecksApiConfig = {
  fetchPollingIntervalSeconds: 0,
};

function createProvider(): ChecksProvider {
  return {
    fetch: () =>
      Promise.resolve({
        responseCode: ResponseCode.OK,
        runs: [],
      }),
  };
}

suite('checks-model tests', () => {
  let model: ChecksModel;

  let current: ChecksProviderState;

  setup(() => {
    model = new ChecksModel(
      testResolver(changeViewModelToken),
      testResolver(changeModelToken),
      getAppContext().reportingService,
      testResolver(pluginLoaderToken).pluginsModel
    );
    model.checksLatest$.subscribe(c => (current = c[PLUGIN_NAME]));
  });

  teardown(() => {
    model.finalize();
  });

  test('register and fetch', async () => {
    let change: ParsedChangeInfo | undefined = undefined;
    testResolver(changeModelToken).change$.subscribe(c => (change = c));
    const provider = createProvider();
    const fetchSpy = sinon.spy(provider, 'fetch');

    model.register({
      pluginName: 'test-plugin',
      provider,
      config: CONFIG_POLLING_NONE,
    });
    await waitUntil(() => change === undefined);

    const testChange = createParsedChange();
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => change === testChange);
    await waitUntilCalled(fetchSpy, 'fetch');

    assert.equal(
      model.latestPatchNum,
      testChange.revisions[testChange.current_revision]
        ._number as PatchSetNumber
    );
    assert.equal(model.changeNum, testChange._number);
  });

  test('fetch throttle', async () => {
    const clock = sinon.useFakeTimers();
    let change: ParsedChangeInfo | undefined = undefined;
    testResolver(changeModelToken).change$.subscribe(c => (change = c));
    const provider = createProvider();
    const fetchSpy = sinon.spy(provider, 'fetch');

    model.register({
      pluginName: 'test-plugin',
      provider,
      config: CONFIG_POLLING_NONE,
    });
    await waitUntil(() => change === undefined);

    const testChange = createParsedChange();
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => change === testChange);

    model.reload('test-plugin');
    model.reload('test-plugin');
    model.reload('test-plugin');

    // Does not emit at 'leading' of throttle interval,
    // because fetch() is not called when change is undefined.
    assert.equal(fetchSpy.callCount, 0);

    // 600 ms is greater than the 500 ms throttle time.
    clock.tick(600);
    // emits at 'trailing' of throttle interval
    assert.equal(fetchSpy.callCount, 1);

    // 600 ms is greater than the 500 ms throttle time.
    clock.tick(600);

    model.reload('test-plugin');
    model.reload('test-plugin');
    model.reload('test-plugin');
    model.reload('test-plugin');
    // emits at 'leading' of throttle interval
    assert.equal(fetchSpy.callCount, 2);

    // 600 ms is greater than the 500 ms throttle time.
    clock.tick(600);
    // emits at 'trailing' of throttle interval
    assert.equal(fetchSpy.callCount, 3);
  });

  test('triggerAction', async () => {
    model.changeNum = 314 as NumericChangeId;
    model.latestPatchNum = 13 as PatchSetNumber;
    const action: Action = {
      name: 'test action',
      callback: () => undefined,
    };
    const spy = sinon.spy(action, 'callback');
    model.triggerAction(action, undefined, 'none');
    assert.isTrue(spy.calledOnce);
    assert.equal(spy.lastCall.args[0], 314);
    assert.equal(spy.lastCall.args[1], 13);
  });

  test('model.updateStateSetProvider', () => {
    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.LATEST);
    assert.deepEqual(current, {
      pluginName: PLUGIN_NAME,
      loading: false,
      firstTimeLoad: true,
      runs: [],
      actions: [],
      links: [],
    });
  });

  test('loading and first time load', () => {
    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.LATEST);
    assert.isFalse(current.loading);
    assert.isTrue(current.firstTimeLoad);
    model.updateStateSetLoading(PLUGIN_NAME, ChecksPatchset.LATEST);
    assert.isTrue(current.loading);
    assert.isTrue(current.firstTimeLoad);
    model.updateStateSetResults(
      PLUGIN_NAME,
      RUNS,
      [],
      [],
      undefined,
      ChecksPatchset.LATEST
    );
    assert.isFalse(current.loading);
    assert.isFalse(current.firstTimeLoad);
    model.updateStateSetLoading(PLUGIN_NAME, ChecksPatchset.LATEST);
    assert.isTrue(current.loading);
    assert.isFalse(current.firstTimeLoad);
    model.updateStateSetResults(
      PLUGIN_NAME,
      RUNS,
      [],
      [],
      undefined,
      ChecksPatchset.LATEST
    );
    assert.isFalse(current.loading);
    assert.isFalse(current.firstTimeLoad);
  });

  test('model.updateStateSetResults', () => {
    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.LATEST);
    model.updateStateSetResults(
      PLUGIN_NAME,
      RUNS,
      [],
      [],
      undefined,
      ChecksPatchset.LATEST
    );
    assert.lengthOf(current.runs, 1);
    assert.lengthOf(current.runs[0].results!, 1);
  });

  test('model.updateStateSetResults ignore empty name or status', () => {
    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.LATEST);
    model.updateStateSetResults(
      PLUGIN_NAME,
      [
        {
          checkName: 'test-check-name',
          status: RunStatus.COMPLETED,
        },
        // Will be ignored, because the checkName is empty.
        {
          checkName: undefined as unknown as string,
          status: RunStatus.COMPLETED,
        },
        // Will be ignored, because the status is empty.
        {
          checkName: 'test-check-name',
          status: undefined as unknown as RunStatus,
        },
      ],
      [],
      [],
      undefined,
      ChecksPatchset.LATEST
    );
    // 2 out of 3 runs are ignored.
    assert.lengthOf(current.runs, 1);
  });

  test('model.updateStateUpdateResult', () => {
    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.LATEST);
    model.updateStateSetResults(
      PLUGIN_NAME,
      RUNS,
      [],
      [],
      undefined,
      ChecksPatchset.LATEST
    );
    assert.equal(
      current.runs[0].results![0].summary,
      RUNS[0]!.results![0].summary
    );
    const result = RUNS[0].results![0];
    const updatedResult = {...result, summary: 'new'};
    model.updateStateUpdateResult(
      PLUGIN_NAME,
      RUNS[0],
      updatedResult,
      ChecksPatchset.LATEST
    );
    assert.lengthOf(current.runs, 1);
    assert.lengthOf(current.runs[0].results!, 1);
    assert.equal(current.runs[0].results![0].summary, 'new');
  });

  test('polls for changes', async () => {
    const clock = sinon.useFakeTimers();
    let change: ParsedChangeInfo | undefined = undefined;
    testResolver(changeModelToken).change$.subscribe(c => (change = c));
    const provider = createProvider();
    const fetchSpy = sinon.spy(provider, 'fetch');

    model.register({
      pluginName: 'test-plugin',
      provider,
      config: CONFIG_POLLING_5S,
    });
    await waitUntil(() => change === undefined);
    clock.tick(1);
    const testChange = createParsedChange();
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => change === testChange);
    clock.tick(600); // need to wait for 500ms throttle
    await waitUntilCalled(fetchSpy, 'fetch');
    const pollCount = fetchSpy.callCount;

    // polling should continue while we wait
    clock.tick(CONFIG_POLLING_5S.fetchPollingIntervalSeconds * 1000 * 2);

    assert.isTrue(fetchSpy.callCount > pollCount);
  });

  test('does not poll when config specifies 0 seconds', async () => {
    const clock = sinon.useFakeTimers();
    let change: ParsedChangeInfo | undefined = undefined;
    testResolver(changeModelToken).change$.subscribe(c => (change = c));
    const provider = createProvider();
    const fetchSpy = sinon.spy(provider, 'fetch');

    model.register({
      pluginName: 'test-plugin',
      provider,
      config: CONFIG_POLLING_NONE,
    });
    await waitUntil(() => change === undefined);
    clock.tick(1);
    const testChange = createParsedChange();
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => change === testChange);
    clock.tick(600); // need to wait for 500ms throttle
    await waitUntilCalled(fetchSpy, 'fetch');
    clock.tick(1);
    const pollCount = fetchSpy.callCount;

    // polling should not happen
    clock.tick(60 * 1000);

    assert.equal(fetchSpy.callCount, pollCount);
  });
});
