// Copyright 2019 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.

#ifndef TEST_WASM_API_TESTS_WASM_API_TEST_H_
#define TEST_WASM_API_TESTS_WASM_API_TEST_H_

#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/zone/accounting-allocator.h"
#include "src/zone/zone.h"
#include "test/common/wasm/wasm-macro-gen.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/wasm-api/wasm.hh"

namespace v8 {
namespace internal {
namespace wasm {

using ::wasm::Engine;
using ::wasm::Extern;
using ::wasm::Foreign;
using ::wasm::Func;
using ::wasm::FuncType;
using ::wasm::Global;
using ::wasm::Instance;
using ::wasm::Memory;
using ::wasm::Module;
using ::wasm::own;
using ::wasm::ownvec;
using ::wasm::Ref;
using ::wasm::Store;
using ::wasm::Table;
using ::wasm::Trap;
using ::wasm::Val;
using ::wasm::ValType;
using ::wasm::vec;

class WasmCapiTest : public ::testing::Test {
 public:
  WasmCapiTest()
      : Test(),
        engine_(Engine::make()),
        allocator_(std::make_unique<AccountingAllocator>()),
        zone_(std::make_unique<Zone>(allocator_.get(), ZONE_NAME)),
        wire_bytes_(zone_.get()),
        builder_(zone_->New<WasmModuleBuilder>(zone_.get())),
        exports_(ownvec<Extern>::make()),
        wasm_i_i_sig_(1, 1, wasm_i_i_sig_types_) {
    store_ = Store::make(engine_.get());
    cpp_i_i_sig_ =
        FuncType::make(ownvec<ValType>::make(ValType::make(::wasm::I32)),
                       ownvec<ValType>::make(ValType::make(::wasm::I32)));
  }

  void Compile() {
    builder_->WriteTo(&wire_bytes_);
    size_t size = wire_bytes_.end() - wire_bytes_.begin();
    vec<byte_t> binary = vec<byte_t>::make(
        size,
        reinterpret_cast<byte_t*>(const_cast<byte*>(wire_bytes_.begin())));

    module_ = Module::make(store_.get(), binary);
    DCHECK_NE(module_.get(), nullptr);
  }

  void Instantiate(Extern* imports[]) {
    Compile();
    instance_ = Instance::make(store_.get(), module_.get(), imports);
    DCHECK_NE(instance_.get(), nullptr);
    exports_ = instance_->exports();
  }

  void AddExportedFunction(Vector<const char> name, byte code[],
                           size_t code_size, FunctionSig* sig) {
    WasmFunctionBuilder* fun = builder()->AddFunction(sig);
    fun->EmitCode(code, static_cast<uint32_t>(code_size));
    fun->Emit(kExprEnd);
    builder()->AddExport(name, fun);
  }

  void AddFunction(byte code[], size_t code_size, FunctionSig* sig) {
    WasmFunctionBuilder* fun = builder()->AddFunction(sig);
    fun->EmitCode(code, static_cast<uint32_t>(code_size));
    fun->Emit(kExprEnd);
  }

  Func* GetExportedFunction(size_t index) {
    DCHECK_GT(exports_.size(), index);
    Extern* exported = exports_[index].get();
    DCHECK_EQ(exported->kind(), ::wasm::EXTERN_FUNC);
    Func* func = exported->func();
    DCHECK_NE(func, nullptr);
    return func;
  }

  Global* GetExportedGlobal(size_t index) {
    DCHECK_GT(exports_.size(), index);
    Extern* exported = exports_[index].get();
    DCHECK_EQ(exported->kind(), ::wasm::EXTERN_GLOBAL);
    Global* global = exported->global();
    DCHECK_NE(global, nullptr);
    return global;
  }

  Memory* GetExportedMemory(size_t index) {
    DCHECK_GT(exports_.size(), index);
    Extern* exported = exports_[index].get();
    DCHECK_EQ(exported->kind(), ::wasm::EXTERN_MEMORY);
    Memory* memory = exported->memory();
    DCHECK_NE(memory, nullptr);
    return memory;
  }

  Table* GetExportedTable(size_t index) {
    DCHECK_GT(exports_.size(), index);
    Extern* exported = exports_[index].get();
    DCHECK_EQ(exported->kind(), ::wasm::EXTERN_TABLE);
    Table* table = exported->table();
    DCHECK_NE(table, nullptr);
    return table;
  }

  void Shutdown() {
    exports_.reset();
    instance_.reset();
    module_.reset();
    store_.reset();
    builder_ = nullptr;
    zone_.reset();
    allocator_.reset();
    engine_.reset();
  }

  WasmModuleBuilder* builder() { return builder_; }
  Engine* engine() { return engine_.get(); }
  Store* store() { return store_.get(); }
  Module* module() { return module_.get(); }
  Instance* instance() { return instance_.get(); }
  const ownvec<Extern>& exports() { return exports_; }
  ZoneBuffer* wire_bytes() { return &wire_bytes_; }

  FunctionSig* wasm_i_i_sig() { return &wasm_i_i_sig_; }
  FuncType* cpp_i_i_sig() { return cpp_i_i_sig_.get(); }

 private:
  own<Engine> engine_;
  own<AccountingAllocator> allocator_;
  own<Zone> zone_;
  ZoneBuffer wire_bytes_;
  WasmModuleBuilder* builder_;
  own<Store> store_;
  own<Module> module_;
  own<Instance> instance_;
  ownvec<Extern> exports_;
  own<FuncType> cpp_i_i_sig_;
  ValueType wasm_i_i_sig_types_[2] = {kWasmI32, kWasmI32};
  FunctionSig wasm_i_i_sig_;
};

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // TEST_WASM_API_TESTS_WASM_API_TEST_H_
