// 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_.ParseBuiltinSemantics();
  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 Cloneable::Clone: request.request = handle
TEST_F(BuiltinSemanticTest, CloneWrite) {
  // Checks that Cloneable::Clone exists in fuchsia.unknown.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.unknown");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.unknown/Cloneable", &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("request", 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 Cloneable::Clone: request.request = handle
TEST_F(BuiltinSemanticTest, CloneRead) {
  // Checks that Cloneable::Clone exists in fuchsia.unknown.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.unknown");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.unknown/Cloneable", &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("request", 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 Cloneable::Clone: request.request = handle
TEST_F(BuiltinSemanticTest, CloneFd) {
  // Checks that Cloneable::Clone exists in fuchsia.unknown.
  Library* library = library_loader_.GetLibraryFromName("fuchsia.unknown");
  ASSERT_NE(library, nullptr);
  library->DecodeTypes();
  Protocol* protocol = nullptr;
  library->GetProtocolByName("fuchsia.unknown/Cloneable", &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("request", 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
