/**
 * @license
 * Copyright 2024 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import * as sinon from 'sinon';
import '../../../../test/common-test-setup';
import {
  SiteBasedCache,
  FetchPromisesCache,
  GrRestApiHelper,
  JSON_PREFIX,
  readJSONResponsePayload,
  parsePrefixedJSON,
} from './gr-rest-api-helper';
import {
  addListenerForTest,
  assertFails,
  makePrefixedJSON,
  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';
import {getBaseUrl} from '../../../../utils/url-util';

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

    test('fetch calls auth fetch and logs', async () => {
      const logStub = sinon.stub(helper, 'logCall');
      const response = new Response(undefined, {status: 404});
      const url = '/my/url';
      const fetchOptions = {method: 'DELETE'};
      authFetchStub.resolves(response);
      const startTime = 123;
      sinon.stub(Date, 'now').returns(startTime);
      helper.fetch({url, fetchOptions, anonymizedUrl: url});

      await assertWriteRequest();
      assert.isTrue(logStub.calledOnce);
      const expectedReq = {
        url: getBaseUrl() + url,
        fetchOptions,
        anonymizedUrl: url,
      };
      assert.deepEqual(logStub.lastCall.args, [
        expectedReq,
        startTime,
        response.status,
      ]);
    });
  });

  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,
          'Network error when trying to fetch. Cause: 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,
          'Network error when trying to fetch. Cause: 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 = makePrefixedJSON(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);
    });

    test('parsing error', async () => {
      const response = new Response('[');
      const err: Error = await assertFails(readJSONResponsePayload(response));
      assert.equal(
        err.message,
        'Response payload is not prefixed json. Payload: ['
      );
    });
  });

  test('logCall only reports requests with anonymized URLs', async () => {
    sinon.stub(Date, 'now').returns(200);
    const handler = sinon.stub();
    addListenerForTest(document, 'gr-rpc-log', handler);

    helper.logCall({url: 'url'}, 100, 200);
    assert.isFalse(handler.called);

    helper.logCall({url: 'url', anonymizedUrl: 'not url'}, 100, 200);
    await waitEventLoop();
    assert.isTrue(handler.calledOnce);
  });
});
