/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../../test/common-test-setup';
import {GrRestApiHelper} from './gr-rest-api-helper-old';
import {assertFails, waitEventLoop} from '../../../../test/test-utils';
import {FakeScheduler} from '../../../../services/scheduler/fake-scheduler';
import {RetryScheduler} from '../../../../services/scheduler/retry-scheduler';
import {ParsedJSON} from '../../../../types/common';
import {HttpMethod} from '../../../../api/rest-api';
import {SinonFakeTimers} from 'sinon';
import {assert} from '@open-wc/testing';
import {AuthService} from '../../../../services/gr-auth/gr-auth';
import {GrAuthMock} from '../../../../services/gr-auth/gr-auth_mock';
import {FetchPromisesCache, SiteBasedCache} from './gr-rest-api-helper';

function makeParsedJSON<T>(val: T): ParsedJSON {
  return val as unknown as ParsedJSON;
}

suite('gr-rest-api-helper tests', () => {
  let clock: SinonFakeTimers;
  let helper: GrRestApiHelper;

  let cache: SiteBasedCache;
  let fetchPromisesCache: FetchPromisesCache;
  let originalCanonicalPath: string | undefined;
  let authFetchStub: sinon.SinonStub;
  let readScheduler: FakeScheduler<Response>;
  let writeScheduler: FakeScheduler<Response>;
  let authService: AuthService;

  setup(() => {
    clock = sinon.useFakeTimers();
    cache = new SiteBasedCache();
    fetchPromisesCache = new FetchPromisesCache();

    originalCanonicalPath = window.CANONICAL_PATH;
    window.CANONICAL_PATH = 'testhelper';

    const testJSON = ')]}\'\n{"hello": "bonjour"}';
    authService = new GrAuthMock();
    authFetchStub = sinon.stub(authService, 'fetch').returns(
      Promise.resolve({
        ...new Response(),
        ok: true,
        text() {
          return Promise.resolve(testJSON);
        },
      })
    );

    readScheduler = new FakeScheduler<Response>();
    writeScheduler = new FakeScheduler<Response>();

    helper = new GrRestApiHelper(
      cache,
      authService,
      fetchPromisesCache,
      readScheduler,
      writeScheduler
    );
  });

  teardown(() => {
    window.CANONICAL_PATH = originalCanonicalPath;
  });

  async function assertReadRequest() {
    assert.equal(readScheduler.scheduled.length, 1);
    await readScheduler.resolve();
    await waitEventLoop();
  }

  async function assertWriteRequest() {
    assert.equal(writeScheduler.scheduled.length, 1);
    await writeScheduler.resolve();
    await waitEventLoop();
  }

  suite('send()', () => {
    setup(() => {
      authFetchStub.returns(
        Promise.resolve({
          ...new Response(),
          ok: true,
          text() {
            return Promise.resolve('Yay');
          },
        })
      );
    });

    test('GET are sent to readScheduler', async () => {
      const promise = helper.send({
        method: HttpMethod.GET,
        url: '/dummy/url',
        parseResponse: false,
      });
      assert.equal(writeScheduler.scheduled.length, 0);
      await assertReadRequest();
      const res: Response = await promise;
      assert.equal(await res.text(), 'Yay');
    });

    test('PUT are sent to writeScheduler', async () => {
      const promise = helper.send({
        method: HttpMethod.PUT,
        url: '/dummy/url',
        parseResponse: false,
      });
      assert.equal(readScheduler.scheduled.length, 0);
      await assertWriteRequest();
      const res: Response = await promise;
      assert.equal(await res.text(), 'Yay');
    });
  });

  suite('fetchJSON()', () => {
    test('Sets header to accept application/json', async () => {
      helper.fetchJSON({url: '/dummy/url'});
      assert.isFalse(authFetchStub.called);
      await assertReadRequest();
      assert.isTrue(authFetchStub.called);
      assert.equal(
        authFetchStub.lastCall.args[1].headers.get('Accept'),
        'application/json'
      );
    });

    test('Use header option accept when provided', async () => {
      const headers = new Headers();
      headers.append('Accept', '*/*');
      const fetchOptions = {headers};
      helper.fetchJSON({url: '/dummy/url', fetchOptions});
      assert.isFalse(authFetchStub.called);
      await assertReadRequest();
      assert.isTrue(authFetchStub.called);
      assert.equal(authFetchStub.lastCall.args[1].headers.get('Accept'), '*/*');
    });

    test('JSON prefix is properly removed', async () => {
      const promise = helper.fetchJSON({url: '/dummy/url'});
      await assertReadRequest();
      const obj = await promise;
      assert.deepEqual(obj, makeParsedJSON({hello: 'bonjour'}));
    });
  });

  test('cached results', () => {
    let n = 0;
    sinon
      .stub(helper, 'fetchJSON')
      .callsFake(() => Promise.resolve(makeParsedJSON(++n)));
    const promises = [];
    promises.push(helper.fetchCacheURL({url: '/foo'}));
    promises.push(helper.fetchCacheURL({url: '/foo'}));
    promises.push(helper.fetchCacheURL({url: '/foo'}));

    return Promise.all(promises).then(results => {
      assert.deepEqual(results, [
        makeParsedJSON(1),
        makeParsedJSON(1),
        makeParsedJSON(1),
      ]);
      return helper.fetchCacheURL({url: '/foo'}).then(foo => {
        assert.equal(foo, makeParsedJSON(1));
      });
    });
  });

  test('cache invalidation', async () => {
    cache.set('/foo/bar', makeParsedJSON(1));
    cache.set('/bar', makeParsedJSON(2));
    fetchPromisesCache.set('/foo/bar', Promise.resolve(makeParsedJSON(3)));
    fetchPromisesCache.set('/bar', Promise.resolve(makeParsedJSON(4)));
    helper.invalidateFetchPromisesPrefix('/foo/');
    assert.isFalse(cache.has('/foo/bar'));
    assert.isTrue(cache.has('/bar'));
    assert.isUndefined(fetchPromisesCache.get('/foo/bar'));
    assert.strictEqual(makeParsedJSON(4), await fetchPromisesCache.get('/bar'));
  });

  test('params are properly encoded', () => {
    let url = helper.urlWithParams('/path/', {
      sp: 'hola',
      gr: 'guten tag',
      noval: null,
    });
    assert.equal(
      url,
      `${window.CANONICAL_PATH}/path/?sp=hola&gr=guten%20tag&noval`
    );

    url = helper.urlWithParams('/path/', {
      sp: 'hola',
      en: ['hey', 'hi'],
    });
    assert.equal(url, `${window.CANONICAL_PATH}/path/?sp=hola&en=hey&en=hi`);

    // Order must be maintained with array params.
    url = helper.urlWithParams('/path/', {
      l: ['c', 'b', 'a'],
    });
    assert.equal(url, `${window.CANONICAL_PATH}/path/?l=c&l=b&l=a`);
  });

  test('request callbacks can be canceled', async () => {
    let cancelCalled = false;
    authFetchStub.returns(
      Promise.resolve({
        body: {
          cancel() {
            cancelCalled = true;
          },
        },
      })
    );
    const cancelCondition = () => true;
    const promise = helper.fetchJSON({url: '/dummy/url', cancelCondition});
    await assertReadRequest();
    const obj = await promise;
    assert.isUndefined(obj);
    assert.isTrue(cancelCalled);
  });

  suite('throwing in errFn', () => {
    function throwInPromise(response?: Response | null, _?: Error) {
      return response?.text().then(text => {
        throw new Error(text);
      });
    }

    function throwImmediately(_1?: Response | null, _2?: Error) {
      throw new Error('Error Callback error');
    }

    setup(() => {
      authFetchStub.returns(
        Promise.resolve({
          ...new Response(),
          status: 400,
          ok: false,
          text() {
            return Promise.resolve('Nope');
          },
        })
      );
    });

    test('errFn with Promise throw cause send to reject on error', async () => {
      const promise = helper.send({
        method: HttpMethod.GET,
        url: '/dummy/url',
        parseResponse: false,
        errFn: throwInPromise,
      });
      await assertReadRequest();

      const err = await assertFails(promise);
      assert.equal((err as Error).message, 'Nope');
    });

    test('errFn with Promise throw cause fetchJSON to reject on error', async () => {
      const promise = helper.fetchJSON({
        url: '/dummy/url',
        errFn: throwInPromise,
      });
      await assertReadRequest();

      const err = await assertFails(promise);
      assert.equal((err as Error).message, 'Nope');
    });

    test('errFn with immediate throw cause send to reject on error', async () => {
      const promise = helper.send({
        method: HttpMethod.GET,
        url: '/dummy/url',
        parseResponse: false,
        errFn: throwImmediately,
      });
      await assertReadRequest();

      const err = await assertFails(promise);
      assert.equal((err as Error).message, 'Error Callback error');
    });

    test('errFn with immediate Promise cause fetchJSON to reject on error', async () => {
      const promise = helper.fetchJSON({
        url: '/dummy/url',
        errFn: throwImmediately,
      });
      await assertReadRequest();

      const err = await assertFails(promise);
      assert.equal((err as Error).message, 'Error Callback error');
    });
  });

  suite('429 errors', () => {
    setup(() => {
      authFetchStub.returns(
        Promise.resolve({
          ...new Response(),
          status: 429,
          ok: false,
        })
      );
    });

    test('still call errFn when not retried', async () => {
      const errFn = sinon.stub();
      const promise = helper.send({
        method: HttpMethod.GET,
        url: '/dummy/url',
        parseResponse: false,
        errFn,
      });
      await assertReadRequest();

      // But we expect the result from the network to return a 429 error when
      // it's no longer being retried.
      await promise;
      assert.isTrue(errFn.called);
    });

    test('still pass through correctly when not retried', async () => {
      const promise = helper.send({
        method: HttpMethod.GET,
        url: '/dummy/url',
        parseResponse: false,
      });
      await assertReadRequest();

      // But we expect the result from the network to return a 429 error when
      // it's no longer being retried.
      const res: Response = await promise;
      assert.equal(res.status, 429);
    });

    test('are retried', async () => {
      helper = new GrRestApiHelper(
        cache,
        authService,
        fetchPromisesCache,
        new RetryScheduler<Response>(readScheduler, 1, 50),
        writeScheduler
      );
      const promise = helper.send({
        method: HttpMethod.GET,
        url: '/dummy/url',
        parseResponse: false,
      });
      await assertReadRequest();
      authFetchStub.returns(
        Promise.resolve({
          ...new Response(),
          ok: true,
          text() {
            return Promise.resolve('Yay');
          },
        })
      );
      // Flush the retry scheduler
      clock.tick(50);
      await waitEventLoop();
      // We expect a retry.
      await assertReadRequest();
      const res: Response = await promise;
      assert.equal(await res.text(), 'Yay');
    });
  });
});
