// Copyright 2020 The Chromium OS 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 <sys/socket.h>

#include <utility>

#include <base/files/file_util.h>
#include <base/run_loop.h>
#include <base/strings/stringprintf.h>
#include <base/test/task_environment.h>
#include <base/threading/thread_task_runner_handle.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus/message.h>
#include <gtest/gtest.h>
#include <vm_concierge/proto_bindings/concierge_service.pb.h>

#include "vm_tools/syslog/log_pipe.h"

namespace vm_tools {
namespace syslog {

// Size of the largest syslog record as defined by RFC3164.
constexpr size_t kMaxSyslogRecord = 1024;

class LogPipeTest : public ::testing::Test {
 public:
  LogPipeTest()
      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}

  void SendVmStartingUpSignal(int cid, LogPipeManager* manager) {
    concierge::VmStartedSignal vm_starting_up_signal;
    vm_starting_up_signal.set_owner_id("test-owner");
    vm_starting_up_signal.set_name(base::StringPrintf("vm-%d", cid));
    vm_starting_up_signal.mutable_vm_info()->set_cid(cid);

    dbus::Signal dbus_signal(concierge::kVmConciergeInterface,
                             concierge::kVmStartingUpSignal);
    dbus::MessageWriter writer(&dbus_signal);
    writer.AppendProtoAsArrayOfBytes(vm_starting_up_signal);

    manager->OnVmStartingUpSignal(&dbus_signal);
  }

  void SendVmStoppedSignal(int cid, LogPipeManager* manager) {
    concierge::VmStoppedSignal vm_stopped_signal;
    vm_stopped_signal.set_cid(cid);

    dbus::Signal dbus_signal(concierge::kVmConciergeInterface,
                             concierge::kVmStoppedSignal);
    dbus::MessageWriter writer(&dbus_signal);
    writer.AppendProtoAsArrayOfBytes(vm_stopped_signal);

    manager->OnVmStoppedSignal(&dbus_signal);
  }

  void CreateTestLogPipe(int cid, LogPipeManager* log_pipe_manager) {
    int log_fds[2];
    auto ret = socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0, log_fds);
    EXPECT_EQ(ret, 0);

    int dest_fds[2];
    ret = socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0, dest_fds);

    log_pipe_manager->CreateLogPipeForTesting(
        cid, vm_tools::VmId("test-owner", base::StringPrintf("vm-%d", cid)),
        base::ScopedFD(dest_fds[0]), base::ScopedFD(log_fds[0]));

    log_sockets_[cid] = base::ScopedFD(log_fds[1]);
    dest_sockets_[cid] = base::ScopedFD(dest_fds[1]);
  }

  void SendOnLogSocket(int64_t cid, const std::string& line) {
    ASSERT_EQ(
        send(log_sockets_[cid].get(), line.c_str(), line.size(), MSG_NOSIGNAL),
        line.size());
  }

  std::string RecvOnDestSocket(int64_t cid) {
    char buf[kMaxSyslogRecord + 1];
    auto ret =
        recv(dest_sockets_[cid].get(), buf, kMaxSyslogRecord, MSG_DONTWAIT);
    return ret > 0 ? std::string(buf) : std::string();
  }

 private:
  std::map<int64_t, base::ScopedFD> log_sockets_;
  std::map<int64_t, base::ScopedFD> dest_sockets_;

  base::test::TaskEnvironment task_environment_;
};

TEST_F(LogPipeTest, ShutdownNoCrash) {
  base::RunLoop run_loop;
  auto manager = std::make_unique<LogPipeManager>(run_loop.QuitClosure());

  SendVmStartingUpSignal(4, manager.get());
  SendVmStartingUpSignal(5, manager.get());

  CreateTestLogPipe(4, manager.get());
  CreateTestLogPipe(5, manager.get());

  std::string log4 = "Log message for cid 4";
  std::string log5 = "Log message for cid 5";

  SendOnLogSocket(4, log4);
  SendOnLogSocket(5, log5);

  base::RunLoop().RunUntilIdle();

  SendVmStoppedSignal(5, manager.get());

  // Logs for cid 4 aren't yet flushed.
  std::string fwd_log4 = RecvOnDestSocket(4);
  EXPECT_TRUE(fwd_log4.empty());

  // Logs for cid 5 are flushed when the VM stops.
  std::string fwd_log5 = RecvOnDestSocket(5);
  EXPECT_NE(fwd_log5.find(log5), std::string::npos);

  base::RunLoop().RunUntilIdle();

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(
          [](std::unique_ptr<LogPipeManager> manager) { manager->OnSigterm(); },
          std::move(manager)));

  run_loop.Run();

  // Logs for cid 4 are flushed when the we SIGTERM.
  fwd_log4 = RecvOnDestSocket(4);
  EXPECT_NE(fwd_log4.find(log4), std::string::npos);

  // No crashing when the destructor runs.
  manager.reset();
}

}  // namespace syslog
}  // namespace vm_tools
