// 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();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/Node", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  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();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/Node", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  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();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/Node", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  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();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/Directory", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  request.AddField("path", std::make_unique<StringValue>("fuchsia.sys.Launcher"));
  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.sys.Launcher");
}

// Check Launcher::CreateComponent.
TEST_F(BuiltinSemanticTest, CreateComponent) {
  // Checks that Launcher::CreateComponent exists in fuchsia.sys.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.sys");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.sys/Launcher", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->GetMethodByName("CreateComponent");
  ASSERT_NE(method, nullptr);
  // Checks that the builtin semantic is defined for CreateComponent.
  ASSERT_NE(method->semantic(), nullptr);

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

  // This message (we only define the fields used by the semantic):
  StructValue request(*method->request());
  auto launch_info = std::make_unique<StructValue>(
      method->request()->SearchMember("launch_info")->type()->AsStructType()->struct_definition());
  launch_info->AddField("url",
                        std::make_unique<StringValue>(
                            "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx"));
  launch_info->AddField("directory_request", std::make_unique<HandleValue>(channel0_));
  request.AddField("launch_info", std::move(launch_info));
  request.AddField("controller", std::make_unique<HandleValue>(channel2_));

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

  // We have these handle semantics for kChannel1 and kChannel3.
  const InferredHandleInfo* inferred_handle_info_1 =
      handle_semantic_.GetInferredHandleInfo(kPid, kChannel1);
  ASSERT_NE(inferred_handle_info_1, nullptr);
  ASSERT_EQ(inferred_handle_info_1->type(), "server");
  ASSERT_EQ(inferred_handle_info_1->path(),
            "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx");
  const InferredHandleInfo* inferred_handle_info_2 =
      handle_semantic_.GetInferredHandleInfo(kPid, kChannel3);
  ASSERT_NE(inferred_handle_info_2, nullptr);
  ASSERT_EQ(inferred_handle_info_2->type(), "server-control");
  ASSERT_EQ(inferred_handle_info_2->path(),
            "fuchsia-pkg://fuchsia.com/echo_server_cpp#meta/echo_server_cpp.cmx");
}

// 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();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/Directory", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  request.AddField("path", std::make_unique<StringValue>("fuchsia.sys.Launcher"));
  request.AddField("object", std::make_unique<HandleValue>(channel0_));

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

// Check short display of File::Seek.
TEST_F(BuiltinSemanticTest, FileSeekShortDisplay) {
  // Checks that Node::Clone exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/File", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  request.AddField("start", 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 Node::Clone exists in fuchsia.io.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.io");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Interface* interface = nullptr;
  library->GetInterfaceByName("fuchsia.io/File", &interface);
  ASSERT_NE(interface, nullptr);
  InterfaceMethod* method = interface->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());
  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
