// 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 <fuchsia/logger/cpp/fidl_test_base.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/syslog/wire_format.h>
#include <zircon/errors.h>
#include <zircon/status.h>

#include <map>
#include <string>
#include <vector>

#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "src/sys/tools/log/log.h"

namespace {

class FakeLogSink : public fuchsia::logger::testing::LogSink_TestBase {
 public:
  explicit FakeLogSink(fidl::InterfaceRequest<fuchsia::logger::LogSink> request)
      : binding_(this, std::move(request)) {}
  void NotImplemented_(const std::string& name) override {
    ADD_FAILURE() << "unexpected call to " << name;
  }
  void Connect(zx::socket socket) override { socket_ = std::move(socket); }
  fpromise::result<std::tuple<zx_time_t, std::string, std::string>, zx_status_t> ReadPacket() {
    static_assert(FX_LOG_MAX_DATAGRAM_LEN == sizeof(fx_log_packet_t));
    std::vector<char> packet(FX_LOG_MAX_DATAGRAM_LEN);
    size_t actual = 0;
    zx_status_t status = socket_.read(0, packet.data(), packet.size(), &actual);
    if (status != ZX_OK) {
      return fpromise::error(status);
    }
    if (actual != packet.size()) {
      // Packet should be exactly one log packet.
      return fpromise::error(ZX_ERR_BAD_STATE);
    }
    if (*packet.rbegin() != 0) {
      // Non-zero final byte indicates an improperly terminated message string.
      return fpromise::error(ZX_ERR_BAD_STATE);
    }
    auto log_packet = reinterpret_cast<const fx_log_packet_t*>(packet.data());
    if (log_packet->data[0] == 0 || log_packet->data[1 + log_packet->data[0]] != 0) {
      // This fake assumes messages have exactly one tag.
      return fpromise::error(ZX_ERR_NOT_SUPPORTED);
    }
    std::string tag(&log_packet->data[1]);
    std::string msg(&log_packet->data[1 + tag.length() + 1]);
    return fpromise::ok(std::make_tuple(log_packet->metadata.time, tag, msg));
  }

  void WaitForInterestChange(WaitForInterestChangeCallback callback) override {}

 private:
  fidl::Binding<fuchsia::logger::LogSink> binding_;
  zx::socket socket_;
};

class LogTest : public gtest::TestLoopFixture {
 protected:
  LogTest() = default;
};

TEST_F(LogTest, InvalidArgc) {
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 0, nullptr), ZX_ERR_INVALID_ARGS);
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 1, nullptr), ZX_ERR_INVALID_ARGS);
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 2, nullptr), ZX_ERR_INVALID_ARGS);
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 4, nullptr), ZX_ERR_INVALID_ARGS);
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 5, nullptr), ZX_ERR_INVALID_ARGS);
}

TEST_F(LogTest, TagTooLong) {
  std::string tag(64, 'x');
  const char* argv[]{"log", tag.c_str(), ""};
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 3, const_cast<char**>(argv)),
            ZX_ERR_OUT_OF_RANGE);
}

TEST_F(LogTest, CombinedTooLong) {
  std::string tag(32, 'x');
  std::string msg(32716, 'x');
  const char* argv[]{"log", tag.c_str(), msg.c_str()};
  EXPECT_EQ(log::ParseAndWriteLog(nullptr, zx::time::infinite(), 3, const_cast<char**>(argv)),
            ZX_ERR_OUT_OF_RANGE);
}

TEST_F(LogTest, SimpleLog) {
  fuchsia::logger::LogSinkHandle log_sink;
  FakeLogSink fake(log_sink.NewRequest());
  const char* argv[]{"log", "hello", "world"};
  auto time = zx::clock::get_monotonic();
  EXPECT_EQ(log::ParseAndWriteLog(std::move(log_sink), time, 3, const_cast<char**>(argv)), ZX_OK);
  RunLoopUntilIdle();
  auto result = fake.ReadPacket();
  ASSERT_TRUE(result.is_ok()) << zx_status_get_string(result.error());
  auto [time_out, tag, msg] = result.take_value();
  EXPECT_EQ(tag, "hello");
  EXPECT_EQ(msg, "world");
  EXPECT_EQ(time_out, time.get());
}

}  // namespace
