// Copyright 2015 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: --harmony-proxies --strong-mode

// Forwarding proxies adapted from proposal definition
function handlerMaker1(obj) {
  return {
    getPropertyDescriptor: function(name) {
      var desc;
      var searchObj = obj;
      while (desc === undefined && searchObj != null) {
        desc = Object.getOwnPropertyDescriptor(searchObj, name);
        searchObj = searchObj.__proto__;
      }
      // a trapping proxy's properties must always be configurable
      if (desc !== undefined) { desc.configurable = true; }
      return desc;
    },
    fix: function() {
      if (Object.isFrozen(obj)) {
        var result = {};
        Object.getOwnPropertyNames(obj).forEach(function(name) {
          result[name] = Object.getOwnPropertyDescriptor(obj, name);
        });
        return result;
      }
      // As long as obj is not frozen, the proxy won't allow itself to be fixed
      return undefined; // will cause a TypeError to be thrown
    }
  };
}
function handlerMaker2(obj) {
  return {
    get: function(receiver, name) {
      return obj[name];
    },
    fix: function() {
      if (Object.isFrozen(obj)) {
        var result = {};
        Object.getOwnPropertyNames(obj).forEach(function(name) {
          result[name] = Object.getOwnPropertyDescriptor(obj, name);
        });
        return result;
      }
      // As long as obj is not frozen, the proxy won't allow itself to be fixed
      return undefined; // will cause a TypeError to be thrown
    }
  };
}
var baseObj = {};
var proxy1 = new Proxy({}, handlerMaker1(baseObj));
var proxy2 = new Proxy({}, handlerMaker2(baseObj));
var childObj1 = { __proto__: proxy1 };
var childObj2 = { __proto__: proxy2 };
var childObjAccessor1 = { set foo(_){}, set "1"(_){}, __proto__: proxy1 };
var childObjAccessor2 = { set foo(_){}, set "1"(_){}, __proto__: proxy2 };

(function() {
  "use strong";
  // TODO(conradw): These asserts are sanity checking V8's proxy implementation.
  // Strong mode semantics for ES6 proxies still need to be explored.
  assertDoesNotThrow(function(){proxy1.foo});
  assertDoesNotThrow(function(){proxy1[1]});
  assertDoesNotThrow(function(){proxy2.foo});
  assertDoesNotThrow(function(){proxy2[1]});
  assertDoesNotThrow(function(){childObj1.foo});
  assertDoesNotThrow(function(){childObj1[1]});
  assertDoesNotThrow(function(){childObj2.foo});
  assertDoesNotThrow(function(){childObj2[1]});
  assertThrows(function(){baseObj.foo}, TypeError);
  assertThrows(function(){baseObj[1]}, TypeError);
  assertThrows(function(){childObjAccessor1.foo}, TypeError);
  assertThrows(function(){childObjAccessor1[1]}, TypeError);
  assertThrows(function(){childObjAccessor2.foo}, TypeError);
  assertThrows(function(){childObjAccessor2[1]}, TypeError);

  // Once the proxy is no longer trapping, property access should have strong
  // semantics.
  Object.freeze(baseObj);

  // TODO(neis): Reenable once proxies properly support freeze.
  //
  // Object.freeze(proxy1);
  // assertThrows(function(){proxy1.foo}, TypeError);
  // assertThrows(function(){proxy1[1]}, TypeError);
  // assertThrows(function(){childObj1.foo}, TypeError);
  // assertThrows(function(){childObj1[1]}, TypeError);
  // assertThrows(function(){childObjAccessor1.foo}, TypeError);
  // assertThrows(function(){childObjAccessor1[1]}, TypeError);
  //
  // Object.freeze(proxy2);
  // assertThrows(function(){proxy2.foo}, TypeError);
  // assertThrows(function(){proxy2[1]}, TypeError);
  // assertThrows(function(){childObj2.foo}, TypeError);
  // assertThrows(function(){childObj2[1]}, TypeError);
  // assertThrows(function(){childObjAccessor2.foo}, TypeError);
  // assertThrows(function(){childObjAccessor2[1]}, TypeError);
})();
