import { test } from 'ember-qunit';
import moduleForIntegration from 'web-client/tests/helpers/module-for-integration';
import run from 'ember-runloop';
import RSVP from 'rsvp';

let service;

function mockFindGameId(gameName) {
  let lookup = {
    'game-1': 1,
    'game-2': 2,
    'game-3': 3,
    'game-4': 4
  };

  return RSVP.resolve(lookup[gameName]);
}

moduleForIntegration('service:watched-games', 'Integration | Service | watched games', {
  beforeEach() {
    let adapter = this.container.lookup('adapter:watched-game');

    adapter._getIndex('watched-games').reset();

    window.localStorage.clear();

    service = this.subject();
    service.set('_maxLength', 3);

    run(() => {
      let store = service.get('store');

      store.createRecord('watched-game', {
        id: '1', timestamp: new Date('January 1, 2015 01:00:00')
      }).save();

      store.createRecord('watched-game', {
        id: '2', timestamp: new Date('January 1, 2015 02:00:00')
      }).save();
    });
  },

  afterEach() {
    service = null;
  }
});

test('`addGame` considers _maxLength and deletes old to make room for new', function (assert) {
  assert.expect(4);

  let done = assert.async();
  let store = service.get('store');

  service._findGameId = mockFindGameId;

  run(() => {
    store.findAll('watched-game').then(function (games) {
      assert.equal(games.get('length'), 2);
    });
  });

  run(() => {
    service.addGame('game-3').then(() => service.addGame('game-4'));
  });

  run(() => {
    store.findAll('watched-game')
      .then(function (watchedGames) {
        assert.equal(watchedGames.get('length'), 3);
        assert.ok(!watchedGames.findBy('id', '1'), 'game 1 is old and deleted');
        assert.ok(watchedGames.findBy('id', '4'), 'game 4 is new and inserted');
        done();
      });
  });
});

test('`addGame` updates timestamp for existing game', function (assert) {
  assert.expect(3);

  let done = assert.async();
  let store = service.get('store');

  service._findGameId = mockFindGameId;

  run(() => {
    store.findAll('watched-game').then(function (games) {
      assert.equal(games.get('length'), 2);
    });
  });

  run(() => {
    service.addGame('game-1');
  });

  run(() => {
    store.findAll('watched-game')
      .then(function (watchedGames) {
        assert.equal(watchedGames.get('length'), 2);

        let g1 = watchedGames.get('firstObject');
        let g2 = watchedGames.get('lastObject');

        assert.ok(g2.get('timestamp') < g1.get('timestamp'), 'game 1 has a more recent timestamp');
        done();
      });
  });
});

test('`addGame` wont try to add a game if one isnt found in ', function (assert) {
  assert.expect(3);

  let done = assert.async();
  let store = service.get('store');

  service._findGameId = mockFindGameId;

  run(() => {
    store.findAll('watched-game').then(function (games) {
      assert.equal(games.get('length'), 2);
    });
  });

  run(() => {
    service.addGame('game-5');
  });

  run(() => {
    store.findAll('watched-game')
      .then(function (watchedGames) {
        assert.equal(watchedGames.get('length'), 2);
        assert.ok(!watchedGames.findBy('id', '5'), 'game 5 was not inserted');
        done();
      });
  });
});
