// Copyright 2017 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.

Debug = debug.Debug

var exception = null;
var object_with_symbol_key = {[Symbol("a")]: 1};
var object_with_callbacks = { toString: () => "string", valueOf: () => 3};
var symbol_for_a = Symbol.for("a");

function listener(event, exec_state, event_data, data) {
  if (event != Debug.DebugEvent.Break) return;
  try {
    function success(expectation, source) {
      var result = exec_state.frame(0).evaluate(source, true).value();
      if (expectation !== undefined) assertEquals(expectation, result);
    }
    function fail(source) {
      assertThrows(() => exec_state.frame(0).evaluate(source, true),
                   EvalError);
    }

    // Test some Object functions.
    success({}, `new Object()`);
    success({p : 3}, `Object.create({}, { p: { value: 3 } })`);
    success("[[\"a\",1],[\"b\",2]]",
            `JSON.stringify(Object.entries({a:1, b:2}))`);
    success({value: 1, writable: true, enumerable: true, configurable: true},
            `Object.getOwnPropertyDescriptor({a: 1}, "a")`);
    success("{\"a\":{\"value\":1,\"writable\":true," +
            "\"enumerable\":true,\"configurable\":true}}",
            `JSON.stringify(Object.getOwnPropertyDescriptors({a: 1}))`);
    success(["a"], `Object.getOwnPropertyNames({a: 1})`);
    success(undefined, `Object.getOwnPropertySymbols(object_with_symbol_key)`);
    success({}, `Object.getPrototypeOf(Object.create({}))`);
    success(true, `Object.is(Object, Object)`);
    success(true, `Object.isExtensible({})`);
    success(false, `Object.isFrozen({})`);
    success(false, `Object.isSealed({})`);
    success([1, 2], `Object.values({a:1, b:2})`);

    fail(`Object.assign({}, {})`);
    fail(`Object.defineProperties({}, [{p:{value:3}}])`);
    fail(`Object.defineProperty({}, {p:{value:3}})`);
    fail(`Object.freeze({})`);
    fail(`Object.preventExtensions({})`);
    fail(`Object.seal({})`);
    fail(`Object.setPrototypeOf({}, {})`);

    // Test some Object.prototype functions.
    success(true, `({a:1}).hasOwnProperty("a")`);
    success(true, `Object.prototype.isPrototypeOf({})`);
    success(true, `({a:1}).propertyIsEnumerable("a")`);
    success("[object Object]", `({a:1}).toString()`);
    success("string", `(object_with_callbacks).toString()`);
    success(3, `(object_with_callbacks).valueOf()`);

    // Test Array functions.
    success([], `new Array()`);
    var function_param = [
      "forEach", "every", "some", "reduce", "reduceRight", "find", "filter",
      "map", "findIndex"
    ];
    var fails = ["toString", "join", "toLocaleString", "pop", "push",
      "reverse", "shift", "unshift", "slice", "splice", "sort", "filter",
      "map", "copyWithin", "fill", "concat"];
    for (f of Object.getOwnPropertyNames(Array.prototype)) {
      if (typeof Array.prototype[f] === "function") {
        if (fails.includes(f)) {
          if (function_param.includes(f)) {
            fail(`[1, 2, 3].${f}(()=>{});`);
          } else {
            fail(`[1, 2, 3].${f}();`);
          }
        } else if (function_param.includes(f)) {
          exec_state.frame(0).evaluate(`[1, 2, 3].${f}(()=>{});`, true);
        } else {
          exec_state.frame(0).evaluate(`[1, 2, 3].${f}();`, true);
        }
      }
    }

    // Test Math functions.
    for (f of Object.getOwnPropertyNames(Math)) {
      if (typeof Math[f] === "function") {
        var result = exec_state.frame(0).evaluate(
                         `Math.${f}(0.5, -0.5);`, true).value();
        if (f != "random") assertEquals(Math[f](0.5, -0.5), result);
      }
    }

    // Test Number functions.
    success(new Number(0), `new Number()`);
    for (f of Object.getOwnPropertyNames(Number)) {
      if (typeof Number[f] === "function") {
        success(Number[f](0.5), `Number.${f}(0.5);`);
      }
    }
    for (f of Object.getOwnPropertyNames(Number.prototype)) {
      if (typeof Number.prototype[f] === "function") {
        if (f == "toLocaleString") continue;
        success(Number(0.5)[f](5), `Number(0.5).${f}(5);`);
      }
    }

    // Test String functions.
    success(new String(), `new String()`);
    success(" ", "String.fromCodePoint(0x20)");
    success(" ", "String.fromCharCode(0x20)");
    for (f of Object.getOwnPropertyNames(String.prototype)) {
      if (typeof String.prototype[f] === "function") {
        // Do not expect locale-specific or regexp-related functions to work.
        // {Lower,Upper}Case (Locale-specific or not) do not work either
        // if Intl is enabled.
        if (f.indexOf("locale") >= 0) continue;
        if (f.indexOf("Locale") >= 0) continue;
        if (typeof Intl !== 'undefined') {
          if (f == "toUpperCase") continue;
          if (f == "toLowerCase") continue;
        }
        if (f == "normalize") continue;
        if (f == "match") continue;
        if (f == "search") continue;
        if (f == "split" || f == "replace") {
          fail(`'abcd'.${f}(2)`);
          continue;
        }
        success("abcd"[f](2), `"abcd".${f}(2);`);
      }
    }
    fail("'abCd'.toLocaleLowerCase()");
    fail("'abcd'.toLocaleUpperCase()");
    if (typeof Intl !== 'undefined') {
      fail("'abCd'.toLowerCase()");
      fail("'abcd'.toUpperCase()");
    }
    fail("'abcd'.match(/a/)");
    fail("'abcd'.replace(/a/)");
    fail("'abcd'.search(/a/)");
    fail("'abcd'.split(/a/)");

    // Test JSON functions.
    success('{"abc":[1,2]}', "JSON.stringify(JSON.parse('{\"abc\":[1,2]}'))");

    // Test Symbol functions.
    success(undefined, `Symbol("a")`);
    fail(`Symbol.for("a")`);  // Symbol.for can be observed via Symbol.keyFor.
    success("a", `Symbol.keyFor(symbol_for_a)`);
    success("Symbol(a)", `symbol_for_a.valueOf().toString()`);
    success("Symbol(a)", `symbol_for_a[Symbol.toPrimitive]().toString()`);
  } catch (e) {
    exception = e;
    print(e, e.stack);
  };
};

// Add the debug event listener.
Debug.setListener(listener);

function f() {
  debugger;
};

f();

assertNull(exception);
