// Copyright 2007-2008 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 <stdlib.h>

#include "v8.h"

#include "heap.h"
#include "cctest.h"

using namespace v8;


enum Expectations {
  EXPECT_RESULT,
  EXPECT_EXCEPTION
};


// A DeclarationContext holds a reference to a v8::Context and keeps
// track of various declaration related counters to make it easier to
// track if global declarations in the presence of interceptors behave
// the right way.
class DeclarationContext {
 public:
  DeclarationContext();

  virtual ~DeclarationContext() {
    if (is_initialized_) {
      context_->Exit();
      context_.Dispose();
    }
  }

  void Check(const char* source,
             int get, int set, int has,
             Expectations expectations,
             v8::Handle<Value> value = Local<Value>());

  int get_count() const { return get_count_; }
  int set_count() const { return set_count_; }
  int has_count() const { return has_count_; }

 protected:
  virtual v8::Handle<Value> Get(Local<String> key);
  virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value);
  virtual v8::Handle<Boolean> Has(Local<String> key);

  void InitializeIfNeeded();

  // Get the holder for the interceptor. Default to the instance template
  // but may be overwritten.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return function->InstanceTemplate();
  }

  // The handlers are called as static functions that forward
  // to the instance specific virtual methods.
  static v8::Handle<Value> HandleGet(Local<String> key,
                                     const AccessorInfo& info);
  static v8::Handle<Value> HandleSet(Local<String> key,
                                     Local<Value> value,
                                     const AccessorInfo& info);
  static v8::Handle<Boolean> HandleHas(Local<String> key,
                                       const AccessorInfo& info);

 private:
  bool is_initialized_;
  Persistent<Context> context_;
  Local<String> property_;

  int get_count_;
  int set_count_;
  int has_count_;

  static DeclarationContext* GetInstance(const AccessorInfo& info);
};


DeclarationContext::DeclarationContext()
    : is_initialized_(false), get_count_(0), set_count_(0), has_count_(0) {
  // Do nothing.
}


void DeclarationContext::InitializeIfNeeded() {
  if (is_initialized_) return;
  HandleScope scope;
  Local<FunctionTemplate> function = FunctionTemplate::New();
  Local<Value> data = External::New(this);
  GetHolder(function)->SetNamedPropertyHandler(&HandleGet,
                                               &HandleSet,
                                               &HandleHas,
                                               0, 0,
                                               data);
  context_ = Context::New(0, function->InstanceTemplate(), Local<Value>());
  context_->Enter();
  is_initialized_ = true;
}


void DeclarationContext::Check(const char* source,
                               int get, int set, int has,
                               Expectations expectations,
                               v8::Handle<Value> value) {
  InitializeIfNeeded();
  // A retry after a GC may pollute the counts, so perform gc now
  // to avoid that.
  v8::internal::Heap::CollectGarbage(0, v8::internal::NEW_SPACE);
  HandleScope scope;
  TryCatch catcher;
  catcher.SetVerbose(true);
  Local<Value> result = Script::Compile(String::New(source))->Run();
  CHECK_EQ(get, get_count());
  CHECK_EQ(set, set_count());
  CHECK_EQ(has, has_count());
  if (expectations == EXPECT_RESULT) {
    CHECK(!catcher.HasCaught());
    if (!value.IsEmpty()) {
      CHECK_EQ(value, result);
    }
  } else {
    CHECK(expectations == EXPECT_EXCEPTION);
    CHECK(catcher.HasCaught());
    if (!value.IsEmpty()) {
      CHECK_EQ(value, catcher.Exception());
    }
  }
}


v8::Handle<Value> DeclarationContext::HandleGet(Local<String> key,
                                                const AccessorInfo& info) {
  DeclarationContext* context = GetInstance(info);
  context->get_count_++;
  return context->Get(key);
}


v8::Handle<Value> DeclarationContext::HandleSet(Local<String> key,
                                                Local<Value> value,
                                                const AccessorInfo& info) {
  DeclarationContext* context = GetInstance(info);
  context->set_count_++;
  return context->Set(key, value);
}


v8::Handle<Boolean> DeclarationContext::HandleHas(Local<String> key,
                                                  const AccessorInfo& info) {
  DeclarationContext* context = GetInstance(info);
  context->has_count_++;
  return context->Has(key);
}


DeclarationContext* DeclarationContext::GetInstance(const AccessorInfo& info) {
  return static_cast<DeclarationContext*>(External::Unwrap(info.Data()));
}


v8::Handle<Value> DeclarationContext::Get(Local<String> key) {
  return v8::Handle<Value>();
}


v8::Handle<Value> DeclarationContext::Set(Local<String> key,
                                          Local<Value> value) {
  return v8::Handle<Value>();
}


v8::Handle<Boolean> DeclarationContext::Has(Local<String> key) {
  return v8::Handle<Boolean>();
}


// Test global declaration of a property the interceptor doesn't know
// about and doesn't handle.
TEST(Unknown) {
  HandleScope scope;

  { DeclarationContext context;
    context.Check("var x; x",
                  1,  // access
                  1,  // declaration
                  2,  // declaration + initialization
                  EXPECT_RESULT, Undefined());
  }

  { DeclarationContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Number::New(0));
  }

  { DeclarationContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1,  // declaration
                  0,
                  EXPECT_RESULT);
  }

  { DeclarationContext context;
    context.Check("const x; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Undefined());
  }

  { DeclarationContext context;
    context.Check("const x = 0; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Undefined());  // SB 0 - BUG 1213579
  }
}



class PresentPropertyContext: public DeclarationContext {
 protected:
  virtual v8::Handle<Boolean> Has(Local<String> key) {
    return True();
  }
};



TEST(Present) {
  HandleScope scope;

  { PresentPropertyContext context;
    context.Check("var x; x",
                  1,  // access
                  0,
                  2,  // declaration + initialization
                  EXPECT_EXCEPTION);  // x is not defined!
  }

  { PresentPropertyContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  1,  // initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Number::New(0));
  }

  { PresentPropertyContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1,  // declaration
                  0,
                  EXPECT_RESULT);
  }

  { PresentPropertyContext context;
    context.Check("const x; x",
                  0,
                  0,
                  1,  // (re-)declaration
                  EXPECT_EXCEPTION);  // x has already been declared!
  }

  { PresentPropertyContext context;
    context.Check("const x = 0; x",
                  0,
                  0,
                  1,  // (re-)declaration
                  EXPECT_EXCEPTION);  // x has already been declared!
  }
}



class AbsentPropertyContext: public DeclarationContext {
 protected:
  virtual v8::Handle<Boolean> Has(Local<String> key) {
    return False();
  }
};


TEST(Absent) {
  HandleScope scope;

  { AbsentPropertyContext context;
    context.Check("var x; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Undefined());
  }

  { AbsentPropertyContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Number::New(0));
  }

  { AbsentPropertyContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1,  // declaration
                  0,
                  EXPECT_RESULT);
  }

  { AbsentPropertyContext context;
    context.Check("const x; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initializetion
                  EXPECT_RESULT, Undefined());
  }

  { AbsentPropertyContext context;
    context.Check("const x = 0; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Undefined());  // SB 0 - BUG 1213579
  }

  { AbsentPropertyContext context;
    context.Check("if (false) { var x = 0 }; x",
                  1,  // access
                  1,  // declaration
                  1,  // declaration + initialization
                  EXPECT_RESULT, Undefined());
  }
}



class AppearingPropertyContext: public DeclarationContext {
 public:
  enum State {
    DECLARE,
    INITIALIZE_IF_ASSIGN,
    UNKNOWN
  };

  AppearingPropertyContext() : state_(DECLARE) { }

 protected:
  virtual v8::Handle<Boolean> Has(Local<String> key) {
    switch (state_) {
      case DECLARE:
        // Force declaration by returning that the
        // property is absent.
        state_ = INITIALIZE_IF_ASSIGN;
        return False();
      case INITIALIZE_IF_ASSIGN:
        // Return that the property is present so we only get the
        // setter called when initializing with a value.
        state_ = UNKNOWN;
        return True();
      default:
        CHECK(state_ == UNKNOWN);
        break;
    }
    // Do the lookup in the object.
    return v8::Local<Boolean>();
  }

 private:
  State state_;
};


TEST(Appearing) {
  HandleScope scope;

  { AppearingPropertyContext context;
    context.Check("var x; x",
                  1,  // access
                  1,  // declaration
                  2,  // declaration + initialization
                  EXPECT_RESULT, Undefined());
  }

  { AppearingPropertyContext context;
    context.Check("var x = 0; x",
                  1,  // access
                  2,  // declaration + initialization
                  2,  // declaration + initialization
                  EXPECT_RESULT, Number::New(0));
  }

  { AppearingPropertyContext context;
    context.Check("function x() { }; x",
                  1,  // access
                  1,  // declaration
                  0,
                  EXPECT_RESULT);
  }

  { AppearingPropertyContext context;
    context.Check("const x; x",
                  0,
                  1,  // declaration
                  2,  // declaration + initialization
                  EXPECT_EXCEPTION);  // x has already been declared!
  }

  { AppearingPropertyContext context;
    context.Check("const x = 0; x",
                  0,
                  1,  // declaration
                  2,  // declaration + initialization
                  EXPECT_EXCEPTION);  //  x has already been declared!
  }
}



class ReappearingPropertyContext: public DeclarationContext {
 public:
  enum State {
    DECLARE,
    DONT_DECLARE,
    INITIALIZE,
    UNKNOWN
  };

  ReappearingPropertyContext() : state_(DECLARE) { }

 protected:
  virtual v8::Handle<Boolean> Has(Local<String> key) {
    switch (state_) {
      case DECLARE:
        // Force the first declaration by returning that
        // the property is absent.
        state_ = DONT_DECLARE;
        return False();
      case DONT_DECLARE:
        // Ignore the second declaration by returning
        // that the property is already there.
        state_ = INITIALIZE;
        return True();
      case INITIALIZE:
        // Force an initialization by returning that
        // the property is absent. This will make sure
        // that the setter is called and it will not
        // lead to redeclaration conflicts (yet).
        state_ = UNKNOWN;
        return False();
      default:
        CHECK(state_ == UNKNOWN);
        break;
    }
    // Do the lookup in the object.
    return v8::Local<Boolean>();
  }

 private:
  State state_;
};


TEST(Reappearing) {
  HandleScope scope;

  { ReappearingPropertyContext context;
    context.Check("const x; var x = 0",
                  0,
                  2,  // var declaration + const initialization
                  4,  // 2 x declaration + 2 x initialization
                  EXPECT_EXCEPTION);  // x has already been declared!
  }
}



class ExistsInPrototypeContext: public DeclarationContext {
 protected:
  virtual v8::Handle<Boolean> Has(Local<String> key) {
    // Let it seem that the property exists in the prototype object.
    return True();
  }

  // Use the prototype as the holder for the interceptors.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return function->PrototypeTemplate();
  }
};


TEST(ExistsInPrototype) {
  HandleScope scope;

  // Sanity check to make sure that the holder of the interceptor
  // really is the prototype object.
  { ExistsInPrototypeContext context;
    context.Check("this.x = 87; this.x",
                  0,
                  0,
                  0,
                  EXPECT_RESULT, Number::New(87));
  }

  { ExistsInPrototypeContext context;
    context.Check("var x; x",
                  1,  // get
                  0,
                  1,  // declaration
                  EXPECT_EXCEPTION);
  }

  { ExistsInPrototypeContext context;
    context.Check("var x = 0; x",
                  0,
                  0,
                  1,  // declaration
                  EXPECT_RESULT, Number::New(0));
  }

  { ExistsInPrototypeContext context;
    context.Check("const x; x",
                  0,
                  0,
                  1,  // declaration
                  EXPECT_RESULT, Undefined());
  }

  { ExistsInPrototypeContext context;
    context.Check("const x = 0; x",
                  0,
                  0,
                  1,  // declaration
                  EXPECT_RESULT, Number::New(0));
  }
}



class AbsentInPrototypeContext: public DeclarationContext {
 protected:
  virtual v8::Handle<Boolean> Has(Local<String> key) {
    // Let it seem that the property is absent in the prototype object.
    return False();
  }

  // Use the prototype as the holder for the interceptors.
  virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
    return function->PrototypeTemplate();
  }
};


TEST(AbsentInPrototype) {
  HandleScope scope;

  { AbsentInPrototypeContext context;
    context.Check("if (false) { var x = 0; }; x",
                  0,
                  0,
                  1,  // declaration
                  EXPECT_RESULT, Undefined());
  }
}
