/**
 * @license
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import '../../../../test/common-test-setup-karma';
import {
  SiteBasedCache,
  FetchPromisesCache,
  GrRestApiHelper,
} from './gr-rest-api-helper';
import {getAppContext} from '../../../../services/app-context';
import {stubAuth} 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';

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>;

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

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

    const testJSON = ')]}\'\n{"hello": "bonjour"}';
    authFetchStub = stubAuth('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,
      getAppContext().authService,
      fetchPromisesCache,
      readScheduler,
      writeScheduler
    );
  });

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

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

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

  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) as Response;
      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) as Response;
      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('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) as Response;
      assert.equal(res.status, 429);
    });

    test('are retried', async () => {
      helper = new GrRestApiHelper(
        cache,
        getAppContext().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 flush();
      // We expect a retry.
      await assertReadRequest();
      const res: Response = (await promise) as Response;
      assert.equal(await res.text(), 'Yay');
    });
  });
});
