// Copyright 2013 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "src/init/v8.h"
#include "src/objects/objects-inl.h"
#include "test/cctest/cctest.h"

using ::v8::Array;
using ::v8::Context;
using ::v8::Local;
using ::v8::Value;

// This test fails if properties on the prototype of the global object appear
// as declared globals.
TEST(StrictUndeclaredGlobalVariable) {
  v8::HandleScope scope(CcTest::isolate());
  v8::Local<v8::String> var_name = v8_str("x");
  LocalContext context;
  v8::TryCatch try_catch(CcTest::isolate());
  v8::Local<v8::Script> script = v8_compile("\"use strict\"; x = 42;");
  v8::Local<v8::Object> proto = v8::Object::New(CcTest::isolate());
  v8::Local<v8::Object> global =
      context->Global()->GetPrototype().As<v8::Object>();
  proto->Set(context.local(), var_name, v8_num(100)).FromJust();
  global->SetPrototype(context.local(), proto).FromJust();
  CHECK(script->Run(context.local()).IsEmpty());
  CHECK(try_catch.HasCaught());
  v8::String::Utf8Value exception(CcTest::isolate(), try_catch.Exception());
  CHECK_EQ(0, strcmp("ReferenceError: x is not defined", *exception));
}


TEST(KeysGlobalObject_Regress2764) {
  LocalContext env1;
  v8::HandleScope scope(env1->GetIsolate());

  // Create second environment.
  v8::Local<Context> env2 = Context::New(env1->GetIsolate());

  Local<Value> token = v8_str("foo");

  // Set same security token for env1 and env2.
  env1->SetSecurityToken(token);
  env2->SetSecurityToken(token);

  // Create a reference to env2 global from env1 global.
  env1->Global()
      ->Set(env1.local(), v8_str("global2"), env2->Global())
      .FromJust();
  // Set some global variables in global2
  env2->Global()->Set(env2, v8_str("a"), v8_str("a")).FromJust();
  env2->Global()->Set(env2, v8_str("42"), v8_str("42")).FromJust();

  // List all entries from global2.
  Local<Array> result;
  result = Local<Array>::Cast(CompileRun("Object.keys(global2)"));
  CHECK_EQ(2u, result->Length());
  CHECK(
      v8_str("42")
          ->Equals(env1.local(), result->Get(env1.local(), 0).ToLocalChecked())
          .FromJust());
  CHECK(
      v8_str("a")
          ->Equals(env1.local(), result->Get(env1.local(), 1).ToLocalChecked())
          .FromJust());

  result =
      Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)"));
  CHECK_LT(2u, result->Length());
  // Check that all elements are in the property names
  ExpectTrue("-1 < Object.getOwnPropertyNames(global2).indexOf('42')");
  ExpectTrue("-1 < Object.getOwnPropertyNames(global2).indexOf('a')");

  // Hold on to global from env2 and detach global from env2.
  env2->DetachGlobal();

  // List again all entries from the detached global2.
  result = Local<Array>::Cast(CompileRun("Object.keys(global2)"));
  CHECK_EQ(0u, result->Length());
  result =
      Local<Array>::Cast(CompileRun("Object.getOwnPropertyNames(global2)"));
  CHECK_EQ(0u, result->Length());
}

TEST(KeysGlobalObject_SetPrototype) {
  LocalContext env1;
  v8::HandleScope scope(env1->GetIsolate());

  // Create second environment.
  v8::Local<Context> env2 = Context::New(env1->GetIsolate());

  Local<Value> token = v8_str("foo");

  // Set same security token for env1 and env2.
  env1->SetSecurityToken(token);
  env2->SetSecurityToken(token);

  // Create a reference to env2 global from env1 global.
  env1->Global()
      ->GetPrototype()
      .As<v8::Object>()
      ->SetPrototype(env1.local(), env2->Global()->GetPrototype())
      .FromJust();
  // Set some global variables in global2
  env2->Global()->Set(env2, v8_str("a"), v8_str("a")).FromJust();
  env2->Global()->Set(env2, v8_str("42"), v8_str("42")).FromJust();

  // List all entries from global2.
  ExpectTrue("a == 'a'");
}
