// 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 "gin/interceptor.h"

#include <stdint.h>

#include "base/bind.h"
#include "gin/arguments.h"
#include "gin/handle.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:
  MyInterceptor(const MyInterceptor&) = delete;
  MyInterceptor& operator=(const MyInterceptor&) = delete;

  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_;
};

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
