/* globals Twitch */
import { moduleFor, test } from 'ember-qunit';
import { stubLogin, restoreLogin } from 'web-client/tests/helpers/stub-login';
import {
  setup as setupMirage, teardown as teardownMirage
} from 'web-client/tests/helpers/setup-mirage-for-integration';
import RSVP from 'rsvp';
import { ARCHIVE_TYPE_PARAM } from 'web-client/utilities/video/types';

moduleFor('service:vod-resume-watching', 'Integration | Service | VOD Resume Watching', {
  integration: true,
  beforeEach() {
    setupMirage(this);
  },
  afterEach() {
    restoreLogin();
    teardownMirage(this);
  }
});

test('#getResumeTime sends new API calls when #clearResumeTimes is called if logged in', function(assert) {
  assert.expect(1);
  stubLogin();

  let service = this.subject();
  let calls = 0;

  this.server.get('https://api.twitch.tv/api/resumewatching/user', function () {
    calls++;
    return { videos: [] };
  });

  let runResumeTime = () => service.getResumeTime('v12345', 54321, ARCHIVE_TYPE_PARAM);
  return runResumeTime().then(() => {
    service.clearResumeTimes();
    runResumeTime();
  }).then(() => {
      assert.equal(calls, 2, '2 API calls are made');
  });
});

test('#getResumeTime only sends 1 API request on multiple calls if logged in', function(assert) {
  assert.expect(2);
  stubLogin();

  let service = this.subject();
  let videoId = 'v12345';
  let position = 300;
  let calls = 0;

  this.server.get('https://api.twitch.tv/api/resumewatching/user', function () {
    assert.equal(++calls, 1, 'only 1 API call is made');
    return {
      videos: [ {video_id: videoId, position} ]
    };
  });

  let runResumeTime = () => service.getResumeTime(videoId, 54321, ARCHIVE_TYPE_PARAM);

  return RSVP.allSettled([
    runResumeTime().then((time) => {
      assert.equal(time, position, `resume time is ${position}`);
    }),
    runResumeTime(),
    runResumeTime()
  ]);
});

test('#getResumeTime gets the resume time when the logged in user has watched the video', function(assert) {
  assert.expect(1);
  let userId = 10000000;
  stubLogin({ username: 'twitch', id: userId });

  let service = this.subject();
  let videoId = 'v12345';
  let position = 800;

  this.server.create('watched-video', {video_id: videoId, position});

  return service.getResumeTime(videoId, 54321, ARCHIVE_TYPE_PARAM).then((time) => {
    assert.equal(time, position, `resume time is ${position}`);
  });
});

test('#getResumeTime gets the resume time when the logged in user has watched the livestream', function(assert) {
  assert.expect(1);
  let userId = 10000000;
  stubLogin({ username: 'twitch', id: userId });

  let service = this.subject();
  let broadcastId = '54321';
  let position = 800;

  this.server.create('watched-video', {video_id: broadcastId, position});

  return service.getResumeTime('v12345', broadcastId, ARCHIVE_TYPE_PARAM).then((time) => {
    assert.equal(time, position, `resume time is ${position}`);
  });
});

test('#getResumeTime gets a null resume time when the logged in user has not watched', function(assert) {
  assert.expect(1);
  let userId = 10000000;
  stubLogin({ username: 'twitch', id: userId });

  let service = this.subject();

  this.server.create('watched-video', {video_id: 'v23456', position: 800});
  this.server.create('watched-video', {video_id: 65432, position: 1000});

  return service.getResumeTime('v12345', 54321, ARCHIVE_TYPE_PARAM).then((time) => {
    assert.equal(time, null, 'resume time is null');
  });
});

test('#getResumeTime return the resume time when the logged out user has watched the video', function(assert) {
  assert.expect(1);

  let service = this.subject();
  let position = 700;

  Twitch.storage.setObject('vodResumeTimes', {v12345: position});

  return service.getResumeTime('v12345', 54321, ARCHIVE_TYPE_PARAM).then((time) => {
    assert.equal(time, position, `resume time is ${position}`);
  });
});

test('#getResumeTime return the resume time when the logged out user has watched the livestream', function(assert) {
  assert.expect(1);

  let service = this.subject();
  let position = 700;

  Twitch.storage.setObject('livestreamResumeTimes', {54321: position});

  return service.getResumeTime('v12345', 54321, ARCHIVE_TYPE_PARAM).then((time) => {
    assert.equal(time, position, `resume time is ${position}`);
  });
});

test('#getResumeTime return a null resume time when the logged out user has not watched', function(assert) {
  assert.expect(1);

  let service = this.subject();

  Twitch.storage.setObject('vodResumeTimes', {v23456: 800});
  Twitch.storage.setObject('livestreamResumeTimes', {65432: 1000});

  return service.getResumeTime('v12345', 54321, ARCHIVE_TYPE_PARAM).then((time) => {
    assert.equal(time, null, 'resume time is null');
  });
});
