/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import * as sinon from 'sinon';
import '../../test/common-test-setup';
import './checks-model';
import {
  CheckResult,
  ChecksModel,
  ChecksPatchset,
  ChecksProviderState,
  RunResult,
  collectRunResults,
} from './checks-model';
import {
  Action,
  Category,
  CheckRun,
  ChecksApiConfig,
  ChecksProvider,
  ResponseCode,
  RunStatus,
} from '../../api/checks';
import {getAppContext} from '../../services/app-context';
import {
  createCheckResult,
  createParsedChange,
  createRun,
} from '../../test/test-data-generators';
import {waitUntil, waitUntilCalled} from '../../test/test-utils';
import {ParsedChangeInfo} from '../../types/types';
import {
  changeModelToken,
  updateRevisionsWithCommitShas,
} 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';
import {deepEqual} from '../../utils/deep-util';

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 = updateRevisionsWithCommitShas(createParsedChange());
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => deepEqual(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 = updateRevisionsWithCommitShas(createParsedChange());
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => deepEqual(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);

    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('allResults$', async () => {
    let results: CheckResult[] | undefined = undefined;
    model.allResults$.subscribe(allResults => (results = allResults));
    testResolver(changeViewModelToken).updateState({
      checksPatchset: 1 as PatchSetNumber,
    });
    testResolver(changeModelToken).updateStateChange(createParsedChange());

    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.SELECTED);
    model.updateStateSetProvider(PLUGIN_NAME, ChecksPatchset.LATEST);
    assert.equal(results!.length, 0);

    model.updateStateSetResults(
      PLUGIN_NAME,
      RUNS,
      [],
      [],
      undefined,
      ChecksPatchset.LATEST
    );
    assert.equal(results!.length, 1);

    model.updateStateSetResults(
      PLUGIN_NAME,
      RUNS,
      [],
      [],
      undefined,
      ChecksPatchset.SELECTED
    );

    assert.equal(results!.length, 1);
  });

  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 = updateRevisionsWithCommitShas(createParsedChange());
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => deepEqual(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 = updateRevisionsWithCommitShas(createParsedChange());
    testResolver(changeModelToken).updateStateChange(testChange);
    await waitUntil(() => deepEqual(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);
  });

  test('collectRunResults does not incur quadratic size increase', async () => {
    const results: CheckResult[] = [];
    for (let i = 0; i < 100; i++) {
      results.push({
        ...createCheckResult({
          message: 'some message',
        }),
      });
    }
    const run = createRun({results});
    let collected: RunResult[] = [];
    collected = collectRunResults(collected, {
      runs: [run],
    } as ChecksProviderState);
    const collectedString = JSON.stringify(collected);
    // If the `results` property would not be removed from every check run, then
    // this combined string would be >1MB in size.
    assert.isAtMost(collectedString.length, 50000);
  });
});
