// 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 "syslog-cat/syslogcat.h"

#include <memory>

#include <sys/socket.h>
#include <sys/un.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>

namespace {

base::ScopedFD CreateDomainSocket(const base::FilePath& path) {
  base::ScopedFD peer(
      HANDLE_EINTR(socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)));

  struct sockaddr_un addr {};
  addr.sun_family = AF_UNIX;
  CHECK_GT(sizeof(addr.sun_path), path.value().length());
  strncpy(addr.sun_path, path.value().c_str(), sizeof(addr.sun_path));
  if (bind(peer.get(), (struct sockaddr*)&addr, sizeof(addr)) == -1) {
    PLOG(ERROR) << "bind";
    return base::ScopedFD();
  }

  if (listen(peer.get(), 1) == -1) {
    PLOG(ERROR) << "listen";
    return base::ScopedFD();
  }

  return peer;
}

base::Optional<std::string> AcceptAndReadFromSocket(int fd, int size) {
  struct sockaddr_un sun_client = {};
  socklen_t socklen = sizeof(sun_client);

  base::ScopedFD fd_client(
      HANDLE_EINTR(accept(fd, (struct sockaddr*)&sun_client, &socklen)));
  if (!fd_client.is_valid())
    return base::nullopt;

  const size_t kBufSize = 1000;
  char buf[kBufSize];
  CHECK_GT(kBufSize, size);
  EXPECT_TRUE(base::ReadFromFD(fd_client.get(), buf, size));
  return std::string(buf, size);
}

}  // anonymous namespace

class SyslogCatTest : public ::testing::Test {
 protected:
  int GetStdOutFd() const {
    CHECK(sock_stdout_.is_valid());
    return sock_stdout_.get();
  }
  int GetStdErrFd() const {
    CHECK(sock_stderr_.is_valid());
    return sock_stderr_.get();
  }

  pid_t ForkAndExecuteSyslogCat(
      const std::vector<const char*>& target_command) {
    const char kIdentifier[] = "IDENT";
    const int kSeverityStdout = 6;
    const int kSeverityStderr = 4;

    pid_t child_pid = fork();
    if (child_pid == 0) {
      // As a child process.
      ExecuteCommandWithRedirection(
          target_command[0], target_command, kIdentifier, kSeverityStdout,
          kSeverityStderr, sock_path_stdout_, sock_path_stderr_);

      return -1;
    } else {
      // As a parent process.
      // Wait for the child process to terminate.
      wait(0);

      return child_pid;
    }
  }

 private:
  void SetUp() override {
    base::FilePath directory;
    CHECK(base::GetTempDir(&directory));
    CHECK(base::CreateTemporaryDirInDir(directory, "syslogcat-test",
                                        &temp_directory_));

    sock_path_stdout_ = temp_directory_.Append("stdout.sock");
    sock_path_stderr_ = temp_directory_.Append("stderr.sock");

    sock_stdout_ = CreateDomainSocket(sock_path_stdout_);
    ASSERT_TRUE(sock_stdout_.is_valid());
    sock_stderr_ = CreateDomainSocket(sock_path_stderr_);
    ASSERT_TRUE(sock_stderr_.is_valid());
  }

  void TearDown() override { base::DeletePathRecursively(temp_directory_); }

  base::FilePath temp_directory_;
  base::FilePath sock_path_stdout_;
  base::FilePath sock_path_stderr_;
  base::ScopedFD sock_stdout_;
  base::ScopedFD sock_stderr_;
};

TEST_F(SyslogCatTest, Echo) {
  pid_t child_pid = ForkAndExecuteSyslogCat(
      std::vector<const char*>({"/bin/echo", "1234567890", NULL}));

  std::string expected_stdout =
      base::StringPrintf("TAG=IDENT[%d]\nPRIORITY=6\n\n1234567890", child_pid);
  base::Optional<std::string> actual_stdout =
      AcceptAndReadFromSocket(GetStdOutFd(), expected_stdout.length());
  EXPECT_TRUE(actual_stdout.has_value());
  EXPECT_EQ(expected_stdout, *actual_stdout);

  std::string expected_stderr =
      base::StringPrintf("TAG=IDENT[%d]\nPRIORITY=4\n\n", child_pid);
  base::Optional<std::string> actual_stderr =
      AcceptAndReadFromSocket(GetStdErrFd(), expected_stderr.length());
  EXPECT_TRUE(actual_stderr.has_value());
  EXPECT_EQ(expected_stderr, *actual_stderr);
}

TEST_F(SyslogCatTest, StdErr) {
  pid_t child_pid = ForkAndExecuteSyslogCat(std::vector<const char*>(
      {"/bin/bash", "-c", ">&2 echo 1234567890", NULL}));

  std::string expected_stdout =
      base::StringPrintf("TAG=IDENT[%d]\nPRIORITY=6\n\n", child_pid);
  base::Optional<std::string> actual_stdout =
      AcceptAndReadFromSocket(GetStdOutFd(), expected_stdout.length());
  EXPECT_TRUE(actual_stdout.has_value());
  EXPECT_EQ(expected_stdout, *actual_stdout);

  std::string expected_stderr =
      base::StringPrintf("TAG=IDENT[%d]\nPRIORITY=4\n\n1234567890", child_pid);
  base::Optional<std::string> actual_stderr =
      AcceptAndReadFromSocket(GetStdErrFd(), expected_stderr.length());
  EXPECT_TRUE(actual_stderr.has_value());
  EXPECT_EQ(expected_stderr, *actual_stderr);
}

TEST_F(SyslogCatTest, StdOutAndErr) {
  pid_t child_pid = ForkAndExecuteSyslogCat(std::vector<const char*>(
      {"/bin/bash", "-c", "echo STDOUT; echo STDERR >&2; echo HELLO.", NULL}));

  std::string expected_stdout = base::StringPrintf(
      "TAG=IDENT[%d]\nPRIORITY=6\n\nSTDOUT\nHELLO.", child_pid);
  base::Optional<std::string> actual_stdout =
      AcceptAndReadFromSocket(GetStdOutFd(), expected_stdout.length());
  EXPECT_TRUE(actual_stdout.has_value());
  EXPECT_EQ(expected_stdout, *actual_stdout);

  std::string expected_stderr =
      base::StringPrintf("TAG=IDENT[%d]\nPRIORITY=4\n\nSTDERR", child_pid);
  base::Optional<std::string> actual_stderr =
      AcceptAndReadFromSocket(GetStdErrFd(), expected_stderr.length());
  EXPECT_TRUE(actual_stderr.has_value());
  EXPECT_EQ(expected_stderr, *actual_stderr);
}
