/**
 * @license
 * Copyright 2024 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../../../test/common-test-setup';
import {
  SiteBasedCache,
  FetchPromisesCache,
  GrRestApiHelper,
  JSON_PREFIX,
  readJSONResponsePayload,
  parsePrefixedJSON,
} from './gr-rest-api-helper';
import {
  addListenerForTest,
  assertFails,
  waitEventLoop,
} from '../../../../test/test-utils';
import {FakeScheduler} from '../../../../services/scheduler/fake-scheduler';
import {RetryScheduler} from '../../../../services/scheduler/retry-scheduler';
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 {ParsedJSON} from '../../../../types/common';

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('fetch()', () => {
    setup(() => {
      authFetchStub.returns(
        Promise.resolve({
          ...new Response(),
          ok: true,
          text() {
            return Promise.resolve('Yay');
          },
        })
      );
    });

    test('GET are sent to readScheduler', async () => {
      const promise = helper.fetch({
        fetchOptions: {
          method: HttpMethod.GET,
        },
        url: '/dummy/url',
      });
      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.fetch({
        fetchOptions: {
          method: HttpMethod.PUT,
        },
        url: '/dummy/url',
      });
      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'}));
    });

    suite('error handling', () => {
      let serverErrorCalled: boolean;
      let networkErrorCalled: boolean;

      setup(() => {
        serverErrorCalled = false;
        networkErrorCalled = false;
        addListenerForTest(document, 'server-error', () => {
          serverErrorCalled = true;
        });
        addListenerForTest(document, 'network-error', () => {
          networkErrorCalled = true;
        });
      });

      test('network error, promise rejects, event thrown', async () => {
        authFetchStub.rejects(new Error('No response'));
        const promise = helper.fetchJSON({url: '/dummy/url'});
        await assertReadRequest();
        const err = await assertFails(promise);
        assert.equal((err as Error).message, 'No response');
        await waitEventLoop();
        assert.isTrue(networkErrorCalled);
        assert.isFalse(serverErrorCalled);
      });

      test('network error, promise rejects, errFn called, no event', async () => {
        const errFn = sinon.stub();
        authFetchStub.rejects(new Error('No response'));
        const promise = helper.fetchJSON({
          url: '/dummy/url',
          errFn,
        });
        await assertReadRequest();
        const err = await assertFails(promise);
        assert.equal((err as Error).message, 'No response');
        await waitEventLoop();
        assert.isTrue(errFn.called);
        assert.isFalse(networkErrorCalled);
        assert.isFalse(serverErrorCalled);
      });

      test('server error, promise resolves undefined, event thrown', async () => {
        authFetchStub.returns(
          Promise.resolve({
            ...new Response(),
            status: 400,
            ok: false,
            text() {
              return Promise.resolve('Nope');
            },
          })
        );
        const promise = helper.fetchJSON({url: '/dummy/url'});
        await assertReadRequest();
        const resp = await promise;
        assert.isUndefined(resp);
        await waitEventLoop();
        assert.isFalse(networkErrorCalled);
        assert.isTrue(serverErrorCalled);
      });

      test('server error, promise resolves undefined, errFn called, no event', async () => {
        authFetchStub.returns(
          Promise.resolve({
            ...new Response(),
            status: 400,
            ok: false,
            text() {
              return Promise.resolve('Nope');
            },
          })
        );
        const errFn = sinon.stub();
        const promise = helper.fetchJSON({url: '/dummy/url', errFn});
        await assertReadRequest();
        const resp = await promise;
        assert.isUndefined(resp);
        await waitEventLoop();
        assert.isTrue(errFn.called);
        assert.isFalse(networkErrorCalled);
        assert.isFalse(serverErrorCalled);
      });

      test('parsing error, promise rejects', async () => {
        authFetchStub.returns(
          Promise.resolve({
            ...new Response(),
            ok: true,
            text() {
              return Promise.resolve('not a prefixed json');
            },
          })
        );
        const errFn = sinon.stub();
        const promise = helper.fetchJSON({url: '/dummy/url', errFn});
        await assertReadRequest();
        await assertFails(promise);
        await waitEventLoop();
        assert.isFalse(errFn.called);
        assert.isFalse(networkErrorCalled);
        assert.isFalse(serverErrorCalled);
      });
    });
  });

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

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

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

    return Promise.all(promises).then(results => {
      assert.deepEqual(results, [
        makeParsedJSON(1),
        // The url without params is queried again, since it has different url.
        makeParsedJSON(2),
        makeParsedJSON(1),
      ]);
      return helper
        .fetchCacheJSON({url: '/foo', params: {hello: 'world'}})
        .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,
      novaltoo: undefined,
    });
    assert.equal(
      url,
      `${window.CANONICAL_PATH}/path/?sp=hola&gr=guten%20tag&noval&novaltoo`
    );

    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`);
  });

  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 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 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('non-retry scheduler errFn is called on 429 error', async () => {
      const errFn = sinon.stub();
      const promise = helper.fetchJSON({
        url: '/dummy/url',
        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('non-retry scheduler 429 error is returned without retrying', async () => {
      const promise = helper.fetch({
        url: '/dummy/url',
      });
      await assertReadRequest();

      // With RetryScheduler we retry if the server returns response with 429
      // status.
      // If we are not using RetryScheduler the response with 429 should simply
      // be returned from fetch without retrying.
      const res: Response = await promise;
      assert.equal(res.status, 429);
    });

    test('With RetryScheduler 429 errors are retried', async () => {
      helper = new GrRestApiHelper(
        cache,
        authService,
        fetchPromisesCache,
        new RetryScheduler<Response>(readScheduler, 1, 50),
        writeScheduler
      );
      const promise = helper.fetch({
        url: '/dummy/url',
      });
      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');
    });
  });

  suite('reading responses', () => {
    test('readResponsePayload', async () => {
      const mockObject = {foo: 'bar', baz: 'foo'} as unknown as ParsedJSON;
      const serial = JSON_PREFIX + JSON.stringify(mockObject);
      const response = new Response(serial);
      const payload = await readJSONResponsePayload(response);
      assert.deepEqual(payload.parsed, mockObject);
      assert.equal(payload.raw, serial);
    });

    test('parsePrefixedJSON', () => {
      const obj = {x: 3, y: {z: 4}, w: 23} as unknown as ParsedJSON;
      const serial = JSON_PREFIX + JSON.stringify(obj);
      const result = parsePrefixedJSON(serial);
      assert.deepEqual(result, obj);
    });
  });
});
