// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --expose-debug-as debug --expose-gc

function testMapMirror(mirror) {
  // Create JSON representation.
  var serializer = debug.MakeMirrorSerializer();
  var json = JSON.stringify(serializer.serializeValue(mirror));

  // Check the mirror hierachy.
  assertTrue(mirror instanceof debug.Mirror);
  assertTrue(mirror instanceof debug.ValueMirror);
  assertTrue(mirror instanceof debug.ObjectMirror);
  assertTrue(mirror instanceof debug.MapMirror);

  assertTrue(mirror.isMap());

  // Parse JSON representation and check.
  var fromJSON = eval('(' + json + ')');
  assertEquals('map', fromJSON.type);
}

function testSetMirror(mirror) {
  // Create JSON representation.
  var serializer = debug.MakeMirrorSerializer();
  var json = JSON.stringify(serializer.serializeValue(mirror));

  // Check the mirror hierachy.
  assertTrue(mirror instanceof debug.Mirror);
  assertTrue(mirror instanceof debug.ValueMirror);
  assertTrue(mirror instanceof debug.ObjectMirror);
  assertTrue(mirror instanceof debug.SetMirror);

  assertTrue(mirror.isSet());

  // Parse JSON representation and check.
  var fromJSON = eval('(' + json + ')');
  assertEquals('set', fromJSON.type);
}

var o1 = new Object();
var o2 = new Object();
var o3 = new Object();

// Test the mirror object for Maps
var map = new Map();
map.set(o1, 11);
map.set(o2, 22);
map.delete(o1);
var mapMirror = debug.MakeMirror(map);
testMapMirror(mapMirror);

var entries = mapMirror.entries();
assertEquals(1, entries.length);
assertSame(o2, entries[0].key);
assertEquals(22, entries[0].value);
map.set(o1, 33);
map.set(o3, o2);
map.delete(o2);
map.set(undefined, 44);

entries = mapMirror.entries();
assertEquals(3, entries.length);
assertSame(o1, entries[0].key);
assertEquals(33, entries[0].value);
assertSame(o3, entries[1].key);
assertSame(o2, entries[1].value);
assertEquals(undefined, entries[2].key);
assertEquals(44, entries[2].value);

assertEquals(3, mapMirror.entries(0).length);
assertEquals(1, mapMirror.entries(1).length);
assertEquals(2, mapMirror.entries(2).length);

// Test the mirror object for Sets
var set = new Set();
set.add(o1);
set.add(o2);
set.delete(o1);
set.add(undefined);
var setMirror = debug.MakeMirror(set);
testSetMirror(setMirror);
var values = setMirror.values();
assertEquals(2, values.length);
assertEquals(1, setMirror.values(1).length);
assertSame(o2, values[0]);
assertEquals(undefined, values[1]);

function initWeakMap(weakMap) {
  weakMap.set(o1, 11);
  weakMap.set(new Object(), 22);
  weakMap.set(o3, 33);
  weakMap.set(new Object(), 44);
  var weakMapMirror = debug.MakeMirror(weakMap);
  testMapMirror(weakMapMirror);
  weakMap.set(new Object(), 55);
  assertTrue(weakMapMirror.entries().length <= 5);
  return weakMapMirror;
}

// Test the mirror object for WeakMaps
var weakMap = new WeakMap();
var weakMapMirror = initWeakMap(weakMap);
gc();

function testWeakMapEntries(weakMapMirror) {
  var entries = weakMapMirror.entries();
  assertEquals(2, entries.length);
  assertEquals(2, weakMapMirror.entries(0).length);
  assertEquals(1, weakMapMirror.entries(1).length);
  var found = 0;
  for (var i = 0; i < entries.length; i++) {
    if (Object.is(entries[i].key, o1)) {
      assertEquals(11, entries[i].value);
      found++;
    }
    if (Object.is(entries[i].key, o3)) {
      assertEquals(33, entries[i].value);
      found++;
    }
  }
  assertEquals(2, found);
}

testWeakMapEntries(weakMapMirror);

function initWeakSet(weakSet) {
  weakSet.add(o1);
  weakSet.add(new Object());
  weakSet.add(o2);
  weakSet.add(new Object());
  weakSet.add(new Object());
  weakSet.add(o3);
  weakSet.delete(o2);
  var weakSetMirror =  debug.MakeMirror(weakSet);
  testSetMirror(weakSetMirror);
  assertTrue(weakSetMirror.values().length <= 5);
  return weakSetMirror;
}

// Test the mirror object for WeakSets
var weakSet = new WeakSet();
var weakSetMirror = initWeakSet(weakSet);
gc();

function testWeakSetValues(weakSetMirror) {
  var values = weakSetMirror.values();
  assertEquals(2, values.length);
  assertEquals(2, weakSetMirror.values(0).length);
  assertEquals(1, weakSetMirror.values(1).length);
  var found = 0;
  for (var i = 0; i < values.length; i++) {
    if (Object.is(values[i], o1)) {
      found++;
    }
    if (Object.is(values[i], o3)) {
      found++;
    }
  }
  assertEquals(2, found);
}

testWeakSetValues(weakSetMirror);
