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

var global = this;
var globalProto = Object.getPrototypeOf(global);

// Number of objects being tested. There is an assert ensuring this is correct.
var objectCount = 21;


function runTest(f) {
  function restore(object, oldProto) {
    delete object[Symbol.unscopables];
    delete object.x;
    delete object.x_;
    delete object.y;
    delete object.z;
    Object.setPrototypeOf(object, oldProto);
  }

  function getObject(i) {
    var objects = [
      {},
      [],
      function() {},
      function() {
        return arguments;
      }(),
      function() {
        'use strict';
        return arguments;
      }(),
      Object(1),
      Object(true),
      Object('bla'),
      new Date,
      new RegExp,
      new Set,
      new Map,
      new WeakMap,
      new WeakSet,
      new ArrayBuffer(10),
      new Int32Array(5),
      Object,
      Function,
      Date,
      RegExp,
      global
    ];

    assertEquals(objectCount, objects.length);
    return objects[i];
  }

  // Tests depends on this not being there to start with.
  delete Array.prototype[Symbol.unscopables];

  if (f.length === 1) {
    for (var i = 0; i < objectCount; i++) {
      var object = getObject(i);
      var oldObjectProto = Object.getPrototypeOf(object);
      f(object);
      restore(object, oldObjectProto);
    }
  } else {
    for (var i = 0; i < objectCount; i++) {
      for (var j = 0; j < objectCount; j++) {
        var object = getObject(i);
        var proto = getObject(j);
        if (object === proto) {
          continue;
        }
        var oldObjectProto = Object.getPrototypeOf(object);
        var oldProtoProto = Object.getPrototypeOf(proto);
        f(object, proto);
        restore(object, oldObjectProto);
        restore(proto, oldProtoProto);
      }
    }
  }
}

// Test array first, since other tests are changing
// Array.prototype[Symbol.unscopables].
function TestArrayPrototypeUnscopables() {
  var descr = Object.getOwnPropertyDescriptor(Array.prototype,
                                              Symbol.unscopables);
  assertFalse(descr.enumerable);
  assertFalse(descr.writable);
  assertTrue(descr.configurable);
  assertEquals(null, Object.getPrototypeOf(descr.value));

  var copyWithin = 'local copyWithin';
  var entries = 'local entries';
  var fill = 'local fill';
  var find = 'local find';
  var findIndex = 'local findIndex';
  var flat = 'local flat';
  var flatMap = 'local flatMap';
  var keys = 'local keys';
  var includes = 'local includes';
  var values = 'local values';

  var array = [];
  array.toString = 42;

  with (array) {
    assertEquals('local copyWithin', copyWithin);
    assertEquals('local entries', entries);
    assertEquals('local fill', fill);
    assertEquals('local find', find);
    assertEquals('local findIndex', findIndex);
    assertEquals('local flat', flat);
    assertEquals('local flatMap', flatMap);
    assertEquals('local includes', includes);
    assertEquals('local keys', keys);
    assertEquals('local values', values);
    assertEquals(42, toString);
  }
}
TestArrayPrototypeUnscopables();



function TestBasics(object) {
  var x = 1;
  var y = 2;
  var z = 3;
  object.x = 4;
  object.y = 5;

  with (object) {
    assertEquals(4, x);
    assertEquals(5, y);
    assertEquals(3, z);
  }

  var truthyValues = [true, 1, 'x', {}, Symbol()];
  for (var truthyValue of truthyValues) {
    object[Symbol.unscopables] = {x: truthyValue};
    with (object) {
      assertEquals(1, x);
      assertEquals(5, y);
      assertEquals(3, z);
    }
  }

  var falsyValues = [false, 0, -0, NaN, '', null, undefined];
  for (var falsyValue of falsyValues) {
    object[Symbol.unscopables] = {x: falsyValue, y: true};
    with (object) {
      assertEquals(4, x);
      assertEquals(2, y);
      assertEquals(3, z);
    }
  }

  for (var xFalsy of falsyValues) {
    for (var yFalsy of falsyValues) {
      object[Symbol.unscopables] = {x: xFalsy, y: yFalsy};
      with (object) {
        assertEquals(4, x);
        assertEquals(5, y);
        assertEquals(3, z);
      }
    }
  }
}
runTest(TestBasics);


function TestUnscopableChain(object) {
  var x = 1;
  object.x = 2;

  with (object) {
    assertEquals(2, x);
  }

  object[Symbol.unscopables] = {
    __proto__: {x: true}
  };
  with (object) {
    assertEquals(1, x);
  }

  object[Symbol.unscopables] = {
    __proto__: {x: undefined}
  };
  with (object) {
    assertEquals(2, x);
  }
}
runTest(TestUnscopableChain);


function TestBasicsSet(object) {
  var x = 1;
  object.x = 2;

  with (object) {
    assertEquals(2, x);
  }

  object[Symbol.unscopables] = {x: true};
  with (object) {
    assertEquals(1, x);
    x = 3;
    assertEquals(3, x);
  }

  assertEquals(3, x);
  assertEquals(2, object.x);
}
runTest(TestBasicsSet);


function TestOnProto(object, proto) {
  var x = 1;
  var y = 2;
  var z = 3;
  proto.x = 4;

  Object.setPrototypeOf(object, proto);
  object.y = 5;

  with (object) {
    assertEquals(4, x);
    assertEquals(5, y);
    assertEquals(3, z);
  }

  proto[Symbol.unscopables] = {x: true};
  with (object) {
    assertEquals(1, x);
    assertEquals(5, y);
    assertEquals(3, z);
  }

  object[Symbol.unscopables] = {y: true};
  with (object) {
    assertEquals(4, x);
    assertEquals(2, y);
    assertEquals(3, z);
  }

  proto[Symbol.unscopables] = {y: true};
  object[Symbol.unscopables] = {x: true};
  with (object) {
    assertEquals(1, x);
    assertEquals(5, y);
    assertEquals(3, z);
  }

  proto[Symbol.unscopables] = {y: true};
  object[Symbol.unscopables] = {x: true, y: undefined};
  with (object) {
    assertEquals(1, x);
    assertEquals(5, y);
    assertEquals(3, z);
  }
}
runTest(TestOnProto);


function TestSetBlockedOnProto(object, proto) {
  var x = 1;
  object.x = 2;

  with (object) {
    assertEquals(2, x);
  }

  Object.setPrototypeOf(object, proto);
  proto[Symbol.unscopables] = {x: true};
  with (object) {
    assertEquals(1, x);
    x = 3;
    assertEquals(3, x);
  }

  assertEquals(3, x);
  assertEquals(2, object.x);
}
runTest(TestSetBlockedOnProto);


function TestNonObject(object) {
  var x = 1;
  var y = 2;
  object.x = 3;
  object.y = 4;

  object[Symbol.unscopables] = 'xy';
  with (object) {
    assertEquals(3, x);
    assertEquals(4, y);
  }

  object[Symbol.unscopables] = null;
  with (object) {
    assertEquals(3, x);
    assertEquals(4, y);
  }
}
runTest(TestNonObject);


function TestChangeDuringWith(object) {
  var x = 1;
  var y = 2;
  object.x = 3;
  object.y = 4;

  with (object) {
    assertEquals(3, x);
    assertEquals(4, y);
    object[Symbol.unscopables] = {x: true};
    assertEquals(1, x);
    assertEquals(4, y);
  }
}
runTest(TestChangeDuringWith);


function TestChangeDuringWithWithPossibleOptimization(object) {
  var x = 1;
  object.x = 2;
  with (object) {
    for (var i = 0; i < 1000; i++) {
      if (i === 500) object[Symbol.unscopables] = {x: true};
      assertEquals(i < 500 ? 2: 1, x);
    }
  }
}
TestChangeDuringWithWithPossibleOptimization({});


function TestChangeDuringWithWithPossibleOptimization2(object) {
  var x = 1;
  object.x = 2;
  object[Symbol.unscopables] = {x: true};
  with (object) {
    for (var i = 0; i < 1000; i++) {
      if (i === 500) delete object[Symbol.unscopables];
      assertEquals(i < 500 ? 1 : 2, x);
    }
  }
}
TestChangeDuringWithWithPossibleOptimization2({});


function TestChangeDuringWithWithPossibleOptimization3(object) {
  var x = 1;
  object.x = 2;
  object[Symbol.unscopables] = {};
  with (object) {
    for (var i = 0; i < 1000; i++) {
      if (i === 500) object[Symbol.unscopables].x = true;
      assertEquals(i < 500 ? 2 : 1, x);
    }
  }
}
TestChangeDuringWithWithPossibleOptimization3({});


function TestChangeDuringWithWithPossibleOptimization4(object) {
  var x = 1;
  object.x = 2;
  object[Symbol.unscopables] = {x: true};
  with (object) {
    for (var i = 0; i < 1000; i++) {
      if (i === 500) delete object[Symbol.unscopables].x;
      assertEquals(i < 500 ? 1 : 2, x);
    }
  }
}
TestChangeDuringWithWithPossibleOptimization4({});


function TestChangeDuringWithWithPossibleOptimization4(object) {
  var x = 1;
  object.x = 2;
  object[Symbol.unscopables] = {x: true};
  with (object) {
    for (var i = 0; i < 1000; i++) {
      if (i === 500) object[Symbol.unscopables].x = undefined;
      assertEquals(i < 500 ? 1 : 2, x);
    }
  }
}
TestChangeDuringWithWithPossibleOptimization4({});


function TestAccessorReceiver(object, proto) {
  var x = 'local';

  Object.defineProperty(proto, 'x', {
    get: function() {
      assertEquals(object, this);
      return this.x_;
    },
    configurable: true
  });
  proto.x_ = 'proto';

  Object.setPrototypeOf(object, proto);
  proto.x_ = 'object';

  with (object) {
    assertEquals('object', x);
  }
}
runTest(TestAccessorReceiver);


function TestUnscopablesGetter(object) {
  // This test gets really messy when object is the global since the assert
  // functions are properties on the global object and the call count gets
  // completely different.
  if (object === global) return;

  var x = 'local';
  object.x = 'object';

  var callCount = 0;
  Object.defineProperty(object, Symbol.unscopables, {
    get: function() {
      callCount++;
      return {};
    },
    configurable: true
  });
  with (object) {
    assertEquals('object', x);
  }
  // Once for HasBinding
  assertEquals(1, callCount);

  callCount = 0;
  Object.defineProperty(object, Symbol.unscopables, {
    get: function() {
      callCount++;
      return {x: true};
    },
    configurable: true
  });
  with (object) {
    assertEquals('local', x);
  }
  // Once for HasBinding
  assertEquals(1, callCount);

  callCount = 0;
  Object.defineProperty(object, Symbol.unscopables, {
    get: function() {
      callCount++;
      return callCount == 1 ? {} : {x: true};
    },
    configurable: true
  });
  with (object) {
    x = 1;
  }
  // Once for HasBinding
  assertEquals(1, callCount);
  assertEquals(1, object.x);
  assertEquals('local', x);
  with (object) {
    x = 2;
  }
  // One more HasBinding.
  assertEquals(2, callCount);
  assertEquals(1, object.x);
  assertEquals(2, x);
}
runTest(TestUnscopablesGetter);


var global = this;
function TestUnscopablesGetter2() {
  var x = 'local';

  var globalProto = Object.getPrototypeOf(global);
  var protos = [{}, [], function() {}, global];
  var objects = [{}, [], function() {}];

  protos.forEach(function(proto) {
    objects.forEach(function(object) {
      Object.defineProperty(proto, 'x', {
        get: function() {
          assertEquals(object, this);
          return 'proto';
        },
        configurable: true
      });

      object.__proto__ = proto;
      Object.defineProperty(object, 'x', {
        get: function() {
          assertEquals(object, this);
          return 'object';
        },
        configurable: true
      });

      with (object) {
        assertEquals('object', x);
      }

      object[Symbol.unscopables] = {x: true};
      with (object) {
        assertEquals('local', x);
      }

      delete proto[Symbol.unscopables];
      delete object[Symbol.unscopables];
    });
  });

  delete global.x;
  Object.setPrototypeOf(global, globalProto);
}
TestUnscopablesGetter2();


function TestSetterOnBlacklisted(object, proto) {
  var x = 'local';
  Object.defineProperty(proto, 'x', {
    set: function(x) {
      assertUnreachable();
    },
    get: function() {
      return 'proto';
    },
    configurable: true
  });
  Object.setPrototypeOf(object, proto);
  Object.defineProperty(object, 'x', {
    get: function() {
      return this.x_;
    },
    set: function(x) {
      this.x_ = x;
    },
    configurable: true
  });
  object.x_ = 1;

  with (object) {
    x = 2;
    assertEquals(2, x);
  }

  assertEquals(2, object.x);

  object[Symbol.unscopables] = {x: true};

  with (object) {
    x = 3;
    assertEquals(3, x);
  }

  assertEquals(2, object.x);
}
runTest(TestSetterOnBlacklisted);


function TestObjectsAsUnscopables(object, unscopables) {
  var x = 1;
  object.x = 2;

  with (object) {
    assertEquals(2, x);
    object[Symbol.unscopables] = unscopables;
    assertEquals(2, x);
  }
}
runTest(TestObjectsAsUnscopables);


function TestAccessorOnUnscopables(object) {
  var x = 1;
  object.x = 2;

  var calls = 0;
  var unscopables = {
    get x() {
      calls++;
      return calls === 1 ? true : undefined;
    }
  };

  with (object) {
    assertEquals(2, x);
    object[Symbol.unscopables] = unscopables;
    assertEquals(1, x);
    assertEquals(2, x);
  }
  assertEquals(2, calls);
}
runTest(TestAccessorOnUnscopables);


function TestLengthUnscopables(object, proto) {
  var length = 2;
  with (object) {
    assertEquals(1, length);
    object[Symbol.unscopables] = {length: true};
    assertEquals(2, length);
    delete object[Symbol.unscopables];
    assertEquals(1, length);
  }
}
TestLengthUnscopables([1], Array.prototype);
TestLengthUnscopables(function(x) {}, Function.prototype);
TestLengthUnscopables(new String('x'), String.prototype);


function TestFunctionNameUnscopables(object) {
  var name = 'local';
  with (object) {
    assertEquals('f', name);
    object[Symbol.unscopables] = {name: true};
    assertEquals('local', name);
    delete object[Symbol.unscopables];
    assertEquals('f', name);
  }
}
TestFunctionNameUnscopables(function f() {});


function TestFunctionPrototypeUnscopables() {
  var prototype = 'local';
  var f = function() {};
  var g = function() {};
  Object.setPrototypeOf(f, g);
  var fp = f.prototype;
  var gp = g.prototype;
  with (f) {
    assertEquals(fp, prototype);
    f[Symbol.unscopables] = {prototype: true};
    assertEquals('local', prototype);
    delete f[Symbol.unscopables];
    assertEquals(fp, prototype);
  }
}
TestFunctionPrototypeUnscopables(function() {});


function TestFunctionArgumentsUnscopables() {
  var func = function() {
    var arguments = 'local';
    var args = func.arguments;
    with (func) {
      assertEquals(args, arguments);
      func[Symbol.unscopables] = {arguments: true};
      assertEquals('local', arguments);
      delete func[Symbol.unscopables];
      assertEquals(args, arguments);
    }
  }
  func(1);
}
TestFunctionArgumentsUnscopables();


function TestArgumentsLengthUnscopables() {
  var func = function() {
    var length = 'local';
    with (arguments) {
      assertEquals(1, length);
      arguments[Symbol.unscopables] = {length: true};
      assertEquals('local', length);
    }
  }
  func(1);
}
TestArgumentsLengthUnscopables();


function TestFunctionCallerUnscopables() {
  var func = function() {
    var caller = 'local';
    with (func) {
      assertEquals(TestFunctionCallerUnscopables, caller);
      func[Symbol.unscopables] = {caller: true};
      assertEquals('local', caller);
      delete func[Symbol.unscopables];
      assertEquals(TestFunctionCallerUnscopables, caller);
    }
  }
  func(1);
}
TestFunctionCallerUnscopables();


function TestGetUnscopablesGetterThrows() {
  var object = {
    get x() {
      assertUnreachable();
    }
  };
  function CustomError() {}
  Object.defineProperty(object, Symbol.unscopables, {
    get: function() {
      throw new CustomError();
    }
  });
  assertThrows(function() {
    with (object) {
      x;
    }
  }, CustomError);
}
TestGetUnscopablesGetterThrows();


function TestGetUnscopablesGetterThrows2() {
  var object = {
    get x() {
      assertUnreachable();
    }
  };
  function CustomError() {}

  object[Symbol.unscopables] = {
    get x() {
      throw new CustomError();
    }
  };
  assertThrows(function() {
    with (object) {
      x;
    }
  }, CustomError);
}
TestGetUnscopablesGetterThrows();
