// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>

#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "gin/arguments.h"
#include "gin/handle.h"
#include "gin/interceptor.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "gin/public/isolate_holder.h"
#include "gin/test/v8_test.h"
#include "gin/try_catch.h"
#include "gin/wrappable.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "v8/include/v8-util.h"

namespace gin {

class MyInterceptor : public Wrappable<MyInterceptor>,
                      public NamedPropertyInterceptor,
                      public IndexedPropertyInterceptor {
 public:
  static WrapperInfo kWrapperInfo;

  static gin::Handle<MyInterceptor> Create(v8::Isolate* isolate) {
    return CreateHandle(isolate, new MyInterceptor(isolate));
  }

  int value() const { return value_; }
  void set_value(int value) { value_ = value; }

  // gin::NamedPropertyInterceptor
  v8::Local<v8::Value> GetNamedProperty(v8::Isolate* isolate,
                                        const std::string& property) override {
    if (property == "value") {
      return ConvertToV8(isolate, value_);
    } else if (property == "func") {
      v8::Local<v8::Context> context = isolate->GetCurrentContext();
      return GetFunctionTemplate(isolate, "func")
          ->GetFunction(context)
          .ToLocalChecked();
    } else {
      return v8::Local<v8::Value>();
    }
  }
  bool SetNamedProperty(v8::Isolate* isolate,
                        const std::string& property,
                        v8::Local<v8::Value> value) override {
    if (property == "value") {
      ConvertFromV8(isolate, value, &value_);
      return true;
    }
    return false;
  }
  std::vector<std::string> EnumerateNamedProperties(
      v8::Isolate* isolate) override {
    std::vector<std::string> result;
    result.push_back("func");
    result.push_back("value");
    return result;
  }

  // gin::IndexedPropertyInterceptor
  v8::Local<v8::Value> GetIndexedProperty(v8::Isolate* isolate,
                                          uint32_t index) override {
    if (index == 0)
      return ConvertToV8(isolate, value_);
    return v8::Local<v8::Value>();
  }
  bool SetIndexedProperty(v8::Isolate* isolate,
                          uint32_t index,
                          v8::Local<v8::Value> value) override {
    if (index == 0) {
      ConvertFromV8(isolate, value, &value_);
      return true;
    }
    // Don't allow bypassing the interceptor.
    return true;
  }
  std::vector<uint32_t> EnumerateIndexedProperties(
      v8::Isolate* isolate) override {
    std::vector<uint32_t> result;
    result.push_back(0);
    return result;
  }

 private:
  explicit MyInterceptor(v8::Isolate* isolate)
      : NamedPropertyInterceptor(isolate, this),
        IndexedPropertyInterceptor(isolate, this),
        value_(0),
        template_cache_(isolate) {}
  ~MyInterceptor() override = default;

  // gin::Wrappable
  ObjectTemplateBuilder GetObjectTemplateBuilder(
      v8::Isolate* isolate) override {
    return Wrappable<MyInterceptor>::GetObjectTemplateBuilder(isolate)
        .AddNamedPropertyInterceptor()
        .AddIndexedPropertyInterceptor();
  }

  int Call(int value) {
    int tmp = value_;
    value_ = value;
    return tmp;
  }

  v8::Local<v8::FunctionTemplate> GetFunctionTemplate(v8::Isolate* isolate,
                                                      const std::string& name) {
    v8::Local<v8::FunctionTemplate> function_template =
        template_cache_.Get(name);
    if (!function_template.IsEmpty())
      return function_template;
    function_template = CreateFunctionTemplate(
        isolate, base::BindRepeating(&MyInterceptor::Call),
        InvokerOptions{true, nullptr});
    template_cache_.Set(name, function_template);
    return function_template;
  }

  int value_;

  v8::StdGlobalValueMap<std::string, v8::FunctionTemplate> template_cache_;

  DISALLOW_COPY_AND_ASSIGN(MyInterceptor);
};

WrapperInfo MyInterceptor::kWrapperInfo = {kEmbedderNativeGin};

class InterceptorTest : public V8Test {
 public:
  void RunInterceptorTest(const std::string& script_source) {
    v8::Isolate* isolate = instance_->isolate();
    v8::HandleScope handle_scope(isolate);

    gin::Handle<MyInterceptor> obj = MyInterceptor::Create(isolate);

    obj->set_value(42);
    EXPECT_EQ(42, obj->value());

    v8::Local<v8::String> source = StringToV8(isolate, script_source);
    EXPECT_FALSE(source.IsEmpty());

    gin::TryCatch try_catch(isolate);
    v8::Local<v8::Script> script =
        v8::Script::Compile(context_.Get(isolate), source).ToLocalChecked();
    v8::Local<v8::Value> val =
        script->Run(context_.Get(isolate)).ToLocalChecked();
    EXPECT_FALSE(val.IsEmpty());
    v8::Local<v8::Function> func;
    EXPECT_TRUE(ConvertFromV8(isolate, val, &func));
    v8::Local<v8::Value> argv[] = {
        ConvertToV8(isolate, obj.get()).ToLocalChecked(),
    };
    func->Call(context_.Get(isolate), v8::Undefined(isolate), 1, argv)
        .ToLocalChecked();
    EXPECT_FALSE(try_catch.HasCaught());
    EXPECT_EQ("", try_catch.GetStackTrace());

    EXPECT_EQ(191, obj->value());
  }
};

TEST_F(InterceptorTest, NamedInterceptor) {
  RunInterceptorTest(
      "(function (obj) {"
      "   if (obj.value !== 42) throw 'FAIL';"
      "   else obj.value = 191; })");
}

TEST_F(InterceptorTest, NamedInterceptorCall) {
  RunInterceptorTest(
      "(function (obj) {"
      "   if (obj.func(191) !== 42) throw 'FAIL';"
      "   })");
}

TEST_F(InterceptorTest, IndexedInterceptor) {
  RunInterceptorTest(
      "(function (obj) {"
      "   if (obj[0] !== 42) throw 'FAIL';"
      "   else obj[0] = 191; })");
}

TEST_F(InterceptorTest, BypassInterceptorAllowed) {
  RunInterceptorTest(
      "(function (obj) {"
      "   obj.value = 191 /* make test happy */;"
      "   obj.foo = 23;"
      "   if (obj.foo !== 23) throw 'FAIL'; })");
}

TEST_F(InterceptorTest, BypassInterceptorForbidden) {
  RunInterceptorTest(
      "(function (obj) {"
      "   obj.value = 191 /* make test happy */;"
      "   obj[1] = 23;"
      "   if (obj[1] === 23) throw 'FAIL'; })");
}

}  // namespace gin
