// Copyright 2020 The Fuchsia 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 <memory>

#include <gtest/gtest.h>

#include "src/lib/fidl_codec/library_loader.h"
#include "src/lib/fidl_codec/semantic.h"
#include "src/lib/fidl_codec/semantic_parser_test.h"
#include "src/lib/fidl_codec/wire_object.h"
#include "src/lib/fidl_codec/wire_types.h"

namespace fidl_codec {
namespace semantic {

constexpr uint64_t kPid = 0x1234;
constexpr uint64_t kTid = 0x4321;
constexpr uint32_t kHandle = 0x1111;
constexpr uint32_t kChannel0 = 0x1000;
constexpr uint32_t kChannel1 = 0x2000;
constexpr uint32_t kChannel2 = 0x3000;
constexpr uint32_t kChannel3 = 0x4000;
constexpr int64_t kEventTimestamp = 0;

class BuiltinSemanticTest : public SemanticParserTest {
 public:
  BuiltinSemanticTest();

  void SetHandleSemantic(std::string_view type, std::string_view path) {
    handle_semantic_.AddInferredHandleInfo(kPid, kHandle, type, path, "");
  }

  void SetHandleSemantic(std::string_view type, int64_t fd) {
    handle_semantic_.AddInferredHandleInfo(kPid, kHandle, type, fd, "");
  }

  void ExecuteWrite(const MethodSemantic* method_semantic, const StructValue* request,
                    const StructValue* response);

  void ExecuteRead(const MethodSemantic* method_semantic, const StructValue* request,
                   const StructValue* response);
  void ShortDisplay(std::ostream& os, const MethodDisplay* display, const StructValue* request,
                    const StructValue* response);

 protected:
  HandleSemantic handle_semantic_;
  const zx_handle_disposition_t channel0_;
  const zx_handle_disposition_t channel2_;
};

BuiltinSemanticTest::BuiltinSemanticTest()
    : channel0_({fidl_codec::kNoHandleDisposition, kChannel0, 0, 0, ZX_OK}),
      channel2_({fidl_codec::kNoHandleDisposition, kChannel2, 0, 0, ZX_OK}) {
  library_loader_.ParseBuiltinSemantic();
  handle_semantic_.AddLinkedHandles(kPid, kChannel0, kChannel1);
  handle_semantic_.AddLinkedHandles(kPid, kChannel2, kChannel3);
}

void BuiltinSemanticTest::ExecuteWrite(const MethodSemantic* method_semantic,
                                       const StructValue* request, const StructValue* response) {
  fidl_codec::semantic::AssignmentSemanticContext context(&handle_semantic_, kPid, kTid, kHandle,
                                                          ContextType::kWrite, request, response,
                                                          kEventTimestamp);
  method_semantic->ExecuteAssignments(&context);
}

void BuiltinSemanticTest::ExecuteRead(const MethodSemantic* method_semantic,
                                      const StructValue* request, const StructValue* response) {
  fidl_codec::semantic::AssignmentSemanticContext context(&handle_semantic_, kPid, kTid, kHandle,
                                                          ContextType::kRead, request, response,
                                                          kEventTimestamp);
  method_semantic->ExecuteAssignments(&context);
}

void BuiltinSemanticTest::ShortDisplay(std::ostream& os, const MethodDisplay* display,
                                       const StructValue* request, const StructValue* response) {
  PrettyPrinter printer(os, WithoutColors, true, "", 100, false);
  fidl_codec::semantic::SemanticContext context(&handle_semantic_, kPid, ZX_HANDLE_INVALID, request,
                                                response, kEventTimestamp);
  bool first_argument = true;
  for (const auto& expression : display->inputs()) {
    if (first_argument) {
      printer << '(';
      first_argument = false;
    } else {
      printer << ", ";
    }
    expression->PrettyPrint(printer, &context);
  }
  if (!first_argument) {
    printer << ')';
  }
  printer << '\n';
  bool first_result = true;
  for (const auto& expression : display->results()) {
    printer << (first_result ? "-> " : ", ");
    first_result = false;
    expression->PrettyPrint(printer, &context);
  }
  if (!first_result) {
    printer << '\n';
  }
}

// Check Node::Clone: request.object = handle
TEST_F(BuiltinSemanticTest, CloneWrite) {
  // Checks that Node::Clone exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/Node", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Clone");
  ASSERT_NE(method, nullptr);
  // Checks that the builtin semantic is defined for Clone.
  ASSERT_NE(method->semantic(), nullptr);

  // Check that by writing on this handle:
  SetHandleSemantic("dir", "/svc");

  // This message (we only define the fields used by the semantic):
  StructValue request(method->request()->AsStructType()->struct_definition());
  request.AddField("object", std::make_unique<HandleValue>(channel0_));

  ExecuteWrite(method->semantic(), &request, nullptr);

  // We have this handle semantic for kChannel1.
  const InferredHandleInfo* inferred_handle_info =
      handle_semantic_.GetInferredHandleInfo(kPid, kChannel1);
  ASSERT_NE(inferred_handle_info, nullptr);
  ASSERT_EQ(inferred_handle_info->type(), "dir");
  ASSERT_EQ(inferred_handle_info->path(), "/svc");
  ASSERT_EQ(inferred_handle_info->attributes(), "cloned");
}

// Check Node::Clone: request.object = handle
TEST_F(BuiltinSemanticTest, CloneRead) {
  // Checks that Node::Clone exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/Node", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Clone");
  ASSERT_NE(method, nullptr);
  // Checks that the builtin semantic is defined for Clone.
  ASSERT_NE(method->semantic(), nullptr);

  // Check that by writing on this handle:
  SetHandleSemantic("dir", "/svc");

  // This message (we only define the fields used by the semantic):
  StructValue request(method->request()->AsStructType()->struct_definition());
  request.AddField("object", std::make_unique<HandleValue>(channel0_));

  ExecuteRead(method->semantic(), &request, nullptr);

  // We have this handle semantic for kChannel1.
  const InferredHandleInfo* inferred_handle_info =
      handle_semantic_.GetInferredHandleInfo(kPid, kChannel0);
  ASSERT_NE(inferred_handle_info, nullptr);
  ASSERT_EQ(inferred_handle_info->type(), "dir");
  ASSERT_EQ(inferred_handle_info->path(), "/svc");
  ASSERT_EQ(inferred_handle_info->attributes(), "cloned");
}

// Check Node::Clone: request.object = handle
TEST_F(BuiltinSemanticTest, CloneFd) {
  // Checks that Node::Clone exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/Node", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Clone");
  ASSERT_NE(method, nullptr);
  // Checks that the builtin semantic is defined for Clone.
  ASSERT_NE(method->semantic(), nullptr);

  // Check that by writing on this handle:
  SetHandleSemantic("handle", 2);

  // This message (we only define the fields used by the semantic):
  StructValue request(method->request()->AsStructType()->struct_definition());
  request.AddField("object", std::make_unique<HandleValue>(channel0_));

  ExecuteRead(method->semantic(), &request, nullptr);

  // We have this handle semantic for kChannel1.
  const InferredHandleInfo* inferred_handle_info =
      handle_semantic_.GetInferredHandleInfo(kPid, kChannel0);
  ASSERT_NE(inferred_handle_info, nullptr);
  ASSERT_EQ(inferred_handle_info->type(), "handle");
  ASSERT_EQ(inferred_handle_info->attributes(), "cloned");
  ASSERT_EQ(inferred_handle_info->fd(), 2);
}

// Check Directory::Open: request.object = handle / request.path
TEST_F(BuiltinSemanticTest, Open) {
  // Checks that Directory::Open exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/Directory", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Open");
  ASSERT_NE(method, nullptr);
  // Checks that the builtin semantic is defined for Open.
  ASSERT_NE(method->semantic(), nullptr);

  // Check that by writing on this handle:
  SetHandleSemantic("dir", "/svc");

  // This message (we only define the fields used by the semantic):
  StructValue request(method->request()->AsStructType()->struct_definition());
  request.AddField("path", std::make_unique<StringValue>("fuchsia.io.Directory"));
  request.AddField("object", std::make_unique<HandleValue>(channel0_));

  ExecuteWrite(method->semantic(), &request, nullptr);

  // We have this handle semantic for kChannel1.
  const InferredHandleInfo* inferred_handle_info =
      handle_semantic_.GetInferredHandleInfo(kPid, kChannel1);
  ASSERT_NE(inferred_handle_info, nullptr);
  ASSERT_EQ(inferred_handle_info->type(), "dir");
  ASSERT_EQ(inferred_handle_info->path(), "/svc/fuchsia.io.Directory");
}

// Check short display of Directory::Open.
TEST_F(BuiltinSemanticTest, OpenShortDisplay) {
  // Checks that Directory::Open exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/Directory", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Open");
  ASSERT_NE(method, nullptr);
  // Checks that the short display is defined for Open.
  ASSERT_NE(method->short_display(), nullptr);

  // This message (we only define the fields used by the display):
  StructValue request(method->request()->AsStructType()->struct_definition());
  request.AddField("path", std::make_unique<StringValue>("fuchsia.io.Directory"));
  request.AddField("object", std::make_unique<HandleValue>(channel0_));

  std::stringstream os;
  ShortDisplay(os, method->short_display(), &request, nullptr);
  ASSERT_EQ(os.str(),
            "(\"fuchsia.io.Directory\")\n"
            "-> 00002000\n");
}

// Check short display of File::Seek.
TEST_F(BuiltinSemanticTest, FileSeekShortDisplay) {
  // Checks that File::Seek exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/File", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Seek");
  ASSERT_NE(method, nullptr);
  // Checks that the short display is defined for Seek.
  ASSERT_NE(method->short_display(), nullptr);

  // This message (we only define the fields used by the display):
  StructValue request(method->request()->AsStructType()->struct_definition());
  request.AddField("origin", std::make_unique<IntegerValue>(0, false));
  request.AddField("offset", std::make_unique<IntegerValue>(1000, false));

  std::stringstream os;
  ShortDisplay(os, method->short_display(), &request, nullptr);
  ASSERT_EQ(os.str(), "(START, 1000)\n");
}

// Check short display of File::Write.
TEST_F(BuiltinSemanticTest, FileWriteShortDisplay) {
  // Checks that File::Write exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.io/File", &protocol);
  ASSERT_NE(protocol, nullptr);
  ProtocolMethod* method = protocol->GetMethodByName("Write");
  ASSERT_NE(method, nullptr);
  // Checks that the short display is defined for Write.
  ASSERT_NE(method->short_display(), nullptr);

  // This message (we only define the fields used by the display):
  StructValue request(method->request()->AsStructType()->struct_definition());
  auto vector = std::make_unique<VectorValue>();
  vector->AddValue(std::make_unique<IntegerValue>(10, false));
  vector->AddValue(std::make_unique<IntegerValue>(20, false));
  vector->AddValue(std::make_unique<IntegerValue>(30, false));
  vector->AddValue(std::make_unique<IntegerValue>(40, false));
  vector->AddValue(std::make_unique<IntegerValue>(50, false));
  request.AddField("data", std::move(vector));

  std::stringstream os;
  ShortDisplay(os, method->short_display(), &request, nullptr);
  ASSERT_EQ(os.str(), "(5 bytes)\n");
}

}  // namespace semantic
}  // namespace fidl_codec
