// 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

Debug = debug.Debug

var exception = null;

function listener(event, exec_state, event_data, data) {
  try {
    if (event == Debug.DebugEvent.Break) {
      exec_state.prepareStep(Debug.StepAction.StepIn);
      print(event_data.sourceLineText());
      assertTrue(
          event_data.sourceLineText().indexOf(`B${breaks++}`) > 0);
    }
  } catch (e) {
    print(e);
    quit();
    exception = e;
  }
}

function cb_set(num) {
  print("element " + num);  // B2 B5 B8
  return true;              // B3 B6 B9
}                           // B4 B7 B10

function cb_map(key, val) {
  print("key " + key + ", value " + val);  // B2 B5 B8
  return true;                             // B3 B6 B9
}                                          // B4 B7 B10

var s = new Set();
s.add(1);
s.add(2);
s.add(3);

var m = new Map();
m.set('foo', 1);
m.set('bar', 2);
m.set('baz', 3);

var breaks = 0;
Debug.setListener(listener);
debugger;                 // B0
s.forEach(cb_set);        // B1
Debug.setListener(null);  // B11
assertNull(exception);
assertEquals(12, breaks);

breaks = 0;
Debug.setListener(listener);
debugger;                 // B0
m.forEach(cb_map);        // B1
Debug.setListener(null);  // B11
assertNull(exception);
assertEquals(12, breaks);

// Test two levels of builtin callbacks:
// Array.forEach calls a callback function, which by itself uses
// Array.forEach with another callback function.

function cb_set_2(num) {
  print("element " + num);  // B3 B6 B9  B15 B18 B21 B27 B30 B33
  return true;              // B4 B7 B10 B16 B19 B22 B28 B31 B34
}                           // B5 B8 B11 B17 B20 B23 B29 B32 B35

function cb_map_2(k, v) {
  print(`key ${k}, value ${v}`);  // B3 B6 B9  B15 B18 B21 B27 B30 B33
  return true;                    // B4 B7 B10 B16 B19 B22 B28 B31 B34
}                                 // B5 B8 B11 B17 B20 B23 B29 B32 B35

function cb_set_foreach(num) {
  s.forEach(cb_set_2);      // B2  B14 B26
  print("back.");           // B12 B24 B36
}                           // B13 B25 B37

function cb_map_foreach(key, val) {
  m.forEach(cb_map_2);      // B2  B14 B26
  print("back.");           // B12 B24 B36
}                           // B13 B25 B37

breaks = 0;
Debug.setListener(listener);
debugger;                   // B0
s.forEach(cb_set_foreach);  // B1
Debug.setListener(null);    // B38
assertNull(exception);
assertEquals(39, breaks);

breaks = 0;
Debug.setListener(listener);
debugger;                   // B0
m.forEach(cb_map_foreach);  // B1
Debug.setListener(null);    // B38
assertNull(exception);
assertEquals(39, breaks);
