// Copyright 2016 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: --allow-natives-syntax

function DataDescriptor(value) {
  return { "enumerable": true, "configurable": true, "writable": true, value };
}


function TestMeta() {
  assertEquals(1, Object.getOwnPropertyDescriptors.length);
  assertEquals(Function.prototype,
               Object.getPrototypeOf(Object.getOwnPropertyDescriptors));
  assertEquals(
      'getOwnPropertyDescriptors', Object.getOwnPropertyDescriptors.name);
  var desc = Reflect.getOwnPropertyDescriptor(
      Object, 'getOwnPropertyDescriptors');
  assertFalse(desc.enumerable);
  assertTrue(desc.writable);
  assertTrue(desc.configurable);
}
TestMeta();


function TestToObject() {
  assertThrows(function() {
    Object.getOwnPropertyDescriptors(null);
  }, TypeError);

  assertThrows(function() {
    Object.getOwnPropertyDescriptors(undefined);
  }, TypeError);

  assertThrows(function() {
    Object.getOwnPropertyDescriptors();
  }, TypeError);
}
TestToObject();


function TestPrototypeProperties() {
  function F() {};
  F.prototype.a = "A";
  F.prototype.b = "B";

  var F2 = new F();
  Object.defineProperties(F2, {
    "b": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "Shadowed 'B'"
    },
    "c": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "C"
    }
  });

  assertEquals({
    "b": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "Shadowed 'B'"
    },
    "c": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "C"
    }
  }, Object.getOwnPropertyDescriptors(F2));
}
TestPrototypeProperties();


function TestPrototypeProperties() {
  function F() {};
  F.prototype.a = "A";
  F.prototype.b = "B";

  var F2 = new F();
  Object.defineProperties(F2, {
    "b": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "Shadowed 'B'"
    },
    "c": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "C"
    }
  });

  assertEquals({
    "b": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "Shadowed 'B'"
    },
    "c": {
      enumerable: false,
      configurable: true,
      writable: false,
      value: "C"
    }
  }, Object.getOwnPropertyDescriptors(F2));
}
TestPrototypeProperties();


function TestTypeFilteringAndOrder() {
  var log = [];
  var sym = Symbol("foo");
  var psym = %CreatePrivateSymbol("private");
  var O = {
    0: 0,
    [sym]: 3,
    "a": 2,
    [psym]: 4,
    1: 1,
  };
  var P = new Proxy(O, {
    ownKeys(target) {
      log.push("ownKeys()");
      return Reflect.ownKeys(target);
    },
    getOwnPropertyDescriptor(target, name) {
      log.push(`getOwnPropertyDescriptor(${String(name)})`);
      return Reflect.getOwnPropertyDescriptor(target, name);
    },
    get(target, name) { assertUnreachable(); },
    set(target, name, value) { assertUnreachable(); },
    deleteProperty(target, name) { assertUnreachable(); },
    defineProperty(target, name, desc) { assertUnreachable(); }
  });

  var result1 = Object.getOwnPropertyDescriptors(O);
  assertEquals({
    0: DataDescriptor(0),
    1: DataDescriptor(1),
    "a": DataDescriptor(2),
    [sym]: DataDescriptor(3)
  }, result1);

  var result2 = Object.getOwnPropertyDescriptors(P);
  assertEquals([
    "ownKeys()",
    "getOwnPropertyDescriptor(0)",
    "getOwnPropertyDescriptor(1)",
    "getOwnPropertyDescriptor(a)",
    "getOwnPropertyDescriptor(Symbol(foo))"
  ], log);
  assertEquals({
    0: DataDescriptor(0),
    1: DataDescriptor(1),
    "a": DataDescriptor(2),
    [sym]: DataDescriptor(3)
  }, result2);
}
TestTypeFilteringAndOrder();


function TestDuplicateKeys() {
  var i = 0;
  var log = [];
  var P = new Proxy({}, {
    ownKeys() {
      log.push(`ownKeys()`);
      return ["A", "A"];
    },
    getOwnPropertyDescriptor(t, name) {
      log.push(`getOwnPropertyDescriptor(${name})`);
      if (i++) return;
      return {
        configurable: true,
        writable: false,
        value: "VALUE"
      };
    },
    get(target, name) { assertUnreachable(); },
    set(target, name, value) { assertUnreachable(); },
    deleteProperty(target, name) { assertUnreachable(); },
    defineProperty(target, name, desc) { assertUnreachable(); }
  });

  var result = Object.getOwnPropertyDescriptors(P);
  assertEquals({
    "A": {
      "value": "VALUE",
      "writable": false,
      "enumerable": false,
      "configurable": true
    }
  }, result);
  assertTrue(result.hasOwnProperty("A"));
  assertEquals([
    "ownKeys()",
    "getOwnPropertyDescriptor(A)",
    "getOwnPropertyDescriptor(A)"
  ], log);
}
TestDuplicateKeys();

function TestFakeProperty() {
  var log = [];
  var P = new Proxy({}, {
    ownKeys() {
      log.push(`ownKeys()`);
      return ["fakeProperty"];
    },
    getOwnPropertyDescriptor(target, name) {
      log.push(`getOwnPropertyDescriptor(${name})`);
      return;
    }
  });
  var result = Object.getOwnPropertyDescriptors(P);
  assertEquals({}, result);
  assertFalse(result.hasOwnProperty("fakeProperty"));
  assertEquals([
    "ownKeys()",
    "getOwnPropertyDescriptor(fakeProperty)"
  ], log);
}
TestFakeProperty();
