import { addItemToDict, addItemToTree, getItemByIdFromDict, getItemSiblingsFromTree, getRootNodeFromTree, resolveItemsMaxBranchLengthInTree, resolveItemPath, getItemsChildrenFromTree } from './TreeItemMap';
var item1 = {
  id: 1,
  name: 'ROOT',
  parentId: 0
};
var item2 = {
  id: 2,
  name: 'LEVEL 2 ITEM 1',
  parentId: 1
};
var item3 = {
  id: 3,
  name: 'LEVEL 2 ITEM 2',
  parentId: 1
};
var item4 = {
  id: 4,
  name: 'LEVEL 3 ITEM 1',
  parentId: 2
};
var item5 = {
  id: 5,
  name: 'LEVEL 3 ITEM 2',
  parentId: 3
};
var item6 = {
  id: 6,
  name: 'LEVEL 4 ITEM 1',
  parentId: 5
};
var outOfStructuresItem = {
  id: 999,
  name: 'OUT OF STRUCTURES',
  parentId: 777
};
var data = [item1, item2, item3, item4, item5, item6];
var dict = {
  1: item1,
  2: item2,
  3: item3,
  4: item4,
  5: item5,
  6: item6
};
var tree = {
  0: [item1],
  1: [item2, item3],
  2: [item4],
  3: [item5],
  5: [item6]
};
describe('TreeItemMap', function () {
  it('should not allow cyclic structures', function (callback) {
    var cyclicData = [{
      id: 1,
      name: 1,
      parentId: 2
    }, {
      id: 2,
      name: 2,
      parentId: 1
    }];

    try {
      var _dict = cyclicData.reduce(function (dict, item) {
        return addItemToDict(item, dict);
      }, {});

      cyclicData.reduce(function (tree, item) {
        return addItemToTree(item, tree, _dict);
      }, {});
      callback('cyclic structure not caught');
    } catch (e) {
      callback();
    }
  });
  it('should map proper flat dictionary from input data', function () {
    var actualDict = data.reduce(function (dict, item) {
      return addItemToDict(item, dict);
    }, {});
    expect(actualDict).toEqual(dict);
  });
  it('should map proper tree structures from input data and dict', function () {
    var actualTree = data.reduce(function (tree, item) {
      return addItemToTree(item, tree, dict);
    }, {});
    expect(actualTree).toEqual(tree);
  });
  describe('getItemByIdFromDict', function () {
    it('should return undefined if id not found', function () {
      var actualItem = getItemByIdFromDict(999, dict);
      expect(actualItem).toBe(undefined);
    });
    it('should resolve item by id', function () {
      var id = item1.id;
      var actualItem = getItemByIdFromDict(id, dict);
      expect(actualItem).toEqual(item1);
    });
  });
  describe('getItemSiblingsFromTree', function () {
    it('should return undefined if id not found', function () {
      var siblings = getItemSiblingsFromTree(999, {});
      expect(siblings).toBe(undefined);
    });
    it('should resolve array of items with same parentId as passed', function () {
      var parentId = item2.parentId;
      var siblings = getItemSiblingsFromTree(item2, tree);
      expect(siblings).toEqual(tree[parentId]);
    });
  });
  describe('getItemsChildrenFromTree', function () {
    it('should return undefined if id not found', function () {
      var children = getItemsChildrenFromTree(outOfStructuresItem, tree);
      expect(children).toBe(undefined);
    });
    it('should resolve array of items with same parentId', function () {
      var id = item1.id;
      var children = getItemsChildrenFromTree(item1, tree);
      expect(children).toEqual(tree[id]);
    });
  });
  describe('getRootNodeFromTree', function () {
    it('should return root node', function () {
      var rootNode = getRootNodeFromTree(tree);
      expect(rootNode).toEqual(tree[0]);
    });
  });
  describe('resolveItemsMaxBranchLengthInTree', function () {
    it('should return 0 for items, that not in map', function () {
      var length = resolveItemsMaxBranchLengthInTree(outOfStructuresItem, tree);
      expect(length).toBe(0);
    });
    it('should return 0 for items without children', function () {
      var length = resolveItemsMaxBranchLengthInTree(item4, tree);
      expect(length).toBe(0);
    });
    it('should return length of longest chain of children', function () {
      var length = resolveItemsMaxBranchLengthInTree(item1, tree);
      var path = resolveItemPath(item6, dict);
      expect(length).toBe(path.length - 1);
    });
  });
  describe('resolveItemPath', function () {
    it('should return nothing if id not found', function () {
      var path = resolveItemPath(outOfStructuresItem, dict);
      expect(path).toBe(undefined);
    });
    it("should get array of item ids leading from passed item to it's root", function () {
      var expectedPath = [1, 2, 4];
      var path = resolveItemPath(item4, dict);
      expect(path).toEqual(expectedPath);
    });
  });
});