// 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 keys = 'local keys';
  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 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();
