import Orbit from 'orbit/core';
import LocalStore from 'orbit/sources/local_store';
import RSVP from 'rsvp';

var store;

var verifyLocalStorageContainsDog = function(dog) {
  var expected = {};
  expected[dog.__id] = dog;
  deepEqual(JSON.parse(window.localStorage.getItem(store.namespace)),
            expected,
            'data in local storage matches expectations');
};

///////////////////////////////////////////////////////////////////////////////

module("Unit - LocalStore", {
  setup: function() {
    Orbit.Promise = RSVP.Promise;
    store = new LocalStore();
  },

  teardown: function() {
    window.localStorage.removeItem(store.namespace);
    store = null;
    Orbit.Promise = null;
  }
});

test("it exists", function() {
  ok(store);
});

test("#insertRecord - can insert records and assign ids", function() {
  expect(7);

  equal(store.length, 0, 'store should be empty');

  stop();
  store.insertRecord({name: 'Hubert', gender: 'm'}).then(function(dog) {
    equal(store.length, 1, 'store should contain one record');
    ok(dog.__id, 'id should be defined');
    equal(dog.name, 'Hubert', 'name should match');
    equal(dog.gender, 'm', 'gender should match');
    return dog;

  }).then(function(dog) {
    verifyLocalStorageContainsDog(dog);
    store.find(dog.id).then(function(foundDog) {
      start();
      equal(foundDog.id, dog.id, 'record can be looked up by id');
    });
  });
});

test("#updateRecord - can update records", function() {
  expect(9);

  equal(store.length, 0, 'store should be empty');

  var original;

  stop();
  store.insertRecord({name: 'Hubert', gender: 'm'}).then(function(dog) {
    original = dog;
    return store.updateRecord({__id: dog.__id, name: 'Beatrice', gender: 'f'}).then(function(updatedDog) {
      equal(updatedDog.__id, dog.__id, '__id remains the same');
      equal(updatedDog.name, 'Beatrice', 'name has been updated');
      equal(updatedDog.gender, 'f', 'gender has been updated');
      return dog;
    });

  }).then(function(dog) {
    verifyLocalStorageContainsDog(dog);
    store.find(dog.__id).then(function(foundDog) {
      start();
      strictEqual(foundDog, original, 'still the same object as the one originally inserted');
      equal(foundDog.__id, dog.__id, 'record can be looked up by __id');
      equal(foundDog.name, 'Beatrice', 'name has been updated');
      equal(foundDog.gender, 'f', 'gender has been updated');
      return dog;
    });
  });
});

test("#patchRecord - can patch records", function() {
  expect(9);

  equal(store.length, 0, 'store should be empty');

  var original;

  stop();
  store.insertRecord({name: 'Hubert', gender: 'm'}).then(function(dog) {
    original = dog;
    return dog;

  }).then(function(dog) {
    return store.patchRecord({__id: dog.__id, name: 'Beatrice'}).then(function(updatedDog) {
      equal(updatedDog.__id, dog.__id, '__id remains the same');
      equal(updatedDog.name, 'Beatrice', 'name has been updated');
      equal(updatedDog.gender, 'm', 'gender has not been updated');
      return dog;
    });

  }).then(function(dog) {
    verifyLocalStorageContainsDog(dog);
    store.find(dog.__id).then(function(foundDog) {
      start();
      strictEqual(foundDog, original, 'still the same object as the one originally inserted');
      equal(foundDog.__id, dog.__id, 'record can be looked up by __id');
      equal(foundDog.name, 'Beatrice', 'name has been updated');
      equal(foundDog.gender, 'm', 'gender has not been updated');
      return dog;
    });
  });
});

test("#destroyRecord - can destroy records", function() {
  expect(4);

  equal(store.length, 0, 'store should be empty');

  stop();
  store.insertRecord({name: 'Hubert', gender: 'm'}).then(function(dog) {
    equal(store.length, 1, 'store should contain one record');

    store.destroyRecord({__id: dog.__id}).then(function() {
      start();
      deepEqual(JSON.parse(window.localStorage.getItem(store.namespace)),
                {},
                'data in local storage matches expectations');
      equal(store.length, 0, 'store should be empty');
    });
  });
});

test("#find - can find all records", function() {
  expect(3);

  equal(store.length, 0, 'store should be empty');

  stop();
  RSVP.all([
    store.insertRecord({name: 'Hubert', gender: 'm'}),
    store.insertRecord({name: 'Beatrice', gender: 'f'}),
    store.insertRecord({name: 'Winky', gender: 'm'})
  ]).then(function() {
    equal(store.length, 3, 'store should contain 3 records');

    store.find().then(function(dogs) {
      start();
      equal(dogs.length, 3, 'find() should return all records');
    });
  });
});

test("it can use a custom local storage namespace for storing data", function() {
  expect(1);

  store.namespace = 'dogs';

  stop();
  store.insertRecord({name: 'Hubert', gender: 'm'}).then(function(dog) {
    start();
    verifyLocalStorageContainsDog(dog);
  });
});

test("autosave can be disabled to delay writing to local storage", function() {
  expect(4);

  store.disableAutosave();

  equal(store.length, 0, 'store should be empty');

  stop();
  store.insertRecord({name: 'Hubert', gender: 'm'}).then(function(dog) {
    start();

    equal(store.length, 1, 'store should contain one record');

    deepEqual(JSON.parse(window.localStorage.getItem(store.namespace)),
              null,
              'local storage should still be empty');

    store.enableAutosave();

    verifyLocalStorageContainsDog(dog);
  });
});


@@ -145,19 +145,22 @@
 Contains
-Dog
+Record
  = funct
@@ -159,27 +159,30 @@
  = function(
-dog
+record
 ) %7B%0A  var ex
@@ -205,19 +205,22 @@
 xpected%5B
-dog
+record
 .__id%5D =
@@ -220,19 +220,22 @@
 __id%5D = 
-dog
+record
 ;%0A  deep
@@ -1259,35 +1259,38 @@
 lStorageContains
-Dog
+Record
 (dog);%0A    store
@@ -2050,35 +2050,38 @@
 lStorageContains
-Dog
+Record
 (dog);%0A    store
@@ -3120,35 +3120,38 @@
 lStorageContains
-Dog
+Record
 (dog);%0A    store
@@ -4891,35 +4891,38 @@
 lStorageContains
-Dog
+Record
 (dog);%0A  %7D);%0A%7D);
@@ -5464,19 +5464,22 @@
 Contains
-Dog
+Record
 (dog);%0A 

Rename `verifyLocalStorageContainsRecord`