/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/logging.h"

#if RTC_LOG_ENABLED()

#include <stdlib.h>

#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <string>
#include <string_view>
#include <utility>

#include "absl/cleanup/cleanup.h"
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/location.h"
#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/platform_thread.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/clock.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

using ::testing::HasSubstr;
using ::testing::StartsWith;

#if defined(WEBRTC_WIN)
constexpr char kFakeFilePath[] = "some\\path\\myfile.cc";
#else
constexpr char kFakeFilePath[] = "some/path/myfile.cc";
#endif

}  // namespace

class LogSinkImpl : public LogSink {
 public:
  explicit LogSinkImpl(std::string* log_data) : log_data_(log_data) {}

  template <typename P>
  explicit LogSinkImpl(P* p) {}

 private:
  void OnLogMessage(const std::string& message) override {
    OnLogMessage(absl::string_view(message));
  }
  void OnLogMessage(absl::string_view message) override {
    log_data_->append(message.begin(), message.end());
  }
  std::string* const log_data_;
};

class LogMessageForTesting : public LogMessage {
 public:
  LogMessageForTesting(const char* file,
                       int line,
                       LoggingSeverity sev,
                       LogErrorContext err_ctx = ERRCTX_NONE,
                       int err = 0)
      : LogMessage(file, line, sev, err_ctx, err) {}

  const std::string& get_extra() const { return extra_; }
#if defined(WEBRTC_ANDROID)
  const char* get_tag() const { return log_line_.tag().data(); }
#endif

  // Returns the contents of the internal log stream.
  // Note that parts of the stream won't (as is) be available until *after* the
  // dtor of the parent class has run. So, as is, this only represents a
  // partially built stream.
  std::string GetPrintStream() {
    RTC_DCHECK(!is_finished_);
    is_finished_ = true;
    FinishPrintStream();
    return print_stream_.Release();
  }

 private:
  bool is_finished_ = false;
};

// Test basic logging operation. We should get the INFO log but not the VERBOSE.
// We should restore the correct global state at the end.
TEST(LogTest, SingleStream) {
  int sev = LogMessage::GetLogToStream(nullptr);

  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream));

  RTC_LOG(LS_INFO) << "INFO";
  RTC_LOG(LS_VERBOSE) << "VERBOSE";
  EXPECT_THAT(str, HasSubstr("INFO"));
  EXPECT_THAT(str, Not(HasSubstr("VERBOSE")));

  int i = 1;
  long l = 2l;
  long long ll = 3ll;

  unsigned int u = 4u;
  unsigned long ul = 5ul;
  unsigned long long ull = 6ull;

  std::string s1 = "char*";
  std::string s2 = "std::string";
  std::string s3 = "absl::stringview";
  const char* null_string = nullptr;
  void* p = reinterpret_cast<void*>(0xabcd);

  // Log all supported types(except doubles/floats) as a sanity-check.
  RTC_LOG(LS_INFO) << "|" << i << "|" << l << "|" << ll << "|" << u << "|" << ul
                   << "|" << ull << "|" << s1.c_str() << "|" << s2 << "|"
                   << absl::string_view(s3) << "|" << p << "|" << null_string
                   << "|";

  // Signed integers
  EXPECT_THAT(str, HasSubstr("|1|"));
  EXPECT_THAT(str, HasSubstr("|2|"));
  EXPECT_THAT(str, HasSubstr("|3|"));

  // Unsigned integers
  EXPECT_THAT(str, HasSubstr("|4|"));
  EXPECT_THAT(str, HasSubstr("|5|"));
  EXPECT_THAT(str, HasSubstr("|6|"));

  // Strings
  EXPECT_THAT(str, HasSubstr("|char*|"));
  EXPECT_THAT(str, HasSubstr("|std::string|"));
  EXPECT_THAT(str, HasSubstr("|absl::stringview|"));

  // void*
  EXPECT_THAT(str, HasSubstr("|abcd|"));

  // null char*
  EXPECT_THAT(str, HasSubstr("|(null)|"));

  LogMessage::RemoveLogToStream(&stream);
  EXPECT_EQ(LS_NONE, LogMessage::GetLogToStream(&stream));
  EXPECT_EQ(sev, LogMessage::GetLogToStream(nullptr));
}

TEST(LogTest, LogStdStringView) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);

  constexpr std::string_view kLongPath =
      "/a/very/long/path/string/that/exceeds/the/small/string/optimization/"
      "buffer/size/which/is/typically/around/fifteen/to/twenty/two/characters/"
      "and/this/is/definitely/longer/than/one/hundred/characters/to/trigger/"
      "any/potential/asan/errors";
  RTC_LOG(LS_INFO) << kLongPath;

  EXPECT_THAT(str, HasSubstr(kLongPath));

  LogMessage::RemoveLogToStream(&stream);
}

TEST(LogTest, LogLongDouble) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);

  long double ld = 123.456789L;
  RTC_LOG(LS_INFO) << ld;

  EXPECT_THAT(str, HasSubstr("123.456"));

  LogMessage::RemoveLogToStream(&stream);
}

TEST(LogTest, LogIfLogIfConditionIsTrue) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);

  RTC_LOG_IF(LS_INFO, true) << "Hello";
  EXPECT_THAT(str, HasSubstr("Hello"));

  LogMessage::RemoveLogToStream(&stream);
}

TEST(LogTest, LogIfDontLogIfConditionIsFalse) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);

  RTC_LOG_IF(LS_INFO, false) << "Hello";
  EXPECT_THAT(str, Not(HasSubstr("Hello")));

  LogMessage::RemoveLogToStream(&stream);
}

TEST(LogTest, LogIfFLogIfConditionIsTrue) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);

  RTC_LOG_IF_F(LS_INFO, true) << "Hello";
  EXPECT_THAT(str, HasSubstr(__FUNCTION__));
  EXPECT_THAT(str, HasSubstr("Hello"));

  LogMessage::RemoveLogToStream(&stream);
}

TEST(LogTest, LogIfFDontLogIfConditionIsFalse) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);

  RTC_LOG_IF_F(LS_INFO, false) << "Not";
  EXPECT_THAT(str, Not(HasSubstr(__FUNCTION__)));
  EXPECT_THAT(str, Not(HasSubstr("Not")));

  LogMessage::RemoveLogToStream(&stream);
}

// Test using multiple log streams. The INFO stream should get the INFO message,
// the VERBOSE stream should get the INFO and the VERBOSE.
// We should restore the correct global state at the end.
TEST(LogTest, MultipleStreams) {
  int sev = LogMessage::GetLogToStream(nullptr);

  std::string str1, str2;
  LogSinkImpl stream1(&str1), stream2(&str2);
  LogMessage::AddLogToStream(&stream1, LS_INFO);
  LogMessage::AddLogToStream(&stream2, LS_VERBOSE);
  EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream1));
  EXPECT_EQ(LS_VERBOSE, LogMessage::GetLogToStream(&stream2));

  RTC_LOG(LS_INFO) << "INFO";
  RTC_LOG(LS_VERBOSE) << "VERBOSE";

  EXPECT_NE(std::string::npos, str1.find("INFO"));
  EXPECT_EQ(std::string::npos, str1.find("VERBOSE"));
  EXPECT_NE(std::string::npos, str2.find("INFO"));
  EXPECT_NE(std::string::npos, str2.find("VERBOSE"));

  LogMessage::RemoveLogToStream(&stream2);
  LogMessage::RemoveLogToStream(&stream1);
  EXPECT_EQ(LS_NONE, LogMessage::GetLogToStream(&stream2));
  EXPECT_EQ(LS_NONE, LogMessage::GetLogToStream(&stream1));

  EXPECT_EQ(sev, LogMessage::GetLogToStream(nullptr));
}

class LogThread {
 public:
  void Start() {
    thread_ = PlatformThread::SpawnJoinable(
        [] { RTC_LOG(LS_VERBOSE) << "RTC_LOG"; }, "LogThread");
  }

 private:
  PlatformThread thread_;
};

// Ensure we don't crash when adding/removing streams while threads are going.
// We should restore the correct global state at the end.
TEST(LogTest, MultipleThreads) {
  int sev = LogMessage::GetLogToStream(nullptr);

  LogThread thread1, thread2, thread3;
  thread1.Start();
  thread2.Start();
  thread3.Start();

  std::string s1, s2, s3;
  LogSinkImpl stream1(&s1), stream2(&s2), stream3(&s3);
  for (int i = 0; i < 1000; ++i) {
    LogMessage::AddLogToStream(&stream1, LS_WARNING);
    LogMessage::AddLogToStream(&stream2, LS_INFO);
    LogMessage::AddLogToStream(&stream3, LS_VERBOSE);
    LogMessage::RemoveLogToStream(&stream1);
    LogMessage::RemoveLogToStream(&stream2);
    LogMessage::RemoveLogToStream(&stream3);
  }

  EXPECT_EQ(sev, LogMessage::GetLogToStream(nullptr));
}

TEST(LogTest, WallClockStartTime) {
  uint32_t time = LogMessage::WallClockStartTime();
  // Expect the time to be in a sensible range, e.g. > 2012-01-01.
  EXPECT_GT(time, 1325376000u);
}

TEST(LogTest, CheckExtraErrorField) {
  LogMessageForTesting log_msg(kFakeFilePath, 100, LS_WARNING, ERRCTX_ERRNO,
                               0xD);
  log_msg.stream() << "This gets added at dtor time";

  EXPECT_THAT(log_msg.get_extra(), StartsWith("[0x0000000D]"));
}

TEST(LogTest, CheckFilePathParsed) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream));
#if defined(WEBRTC_ANDROID)
  const char* tag = nullptr;
#endif
  {
    LogMessageForTesting log_msg(kFakeFilePath, 100, LS_INFO);
    log_msg.stream() << "<- Does this look right?";
#if defined(WEBRTC_ANDROID)
    tag = log_msg.get_tag();
#endif
  }

#if defined(WEBRTC_ANDROID)
  EXPECT_NE(nullptr, strstr(tag, "myfile.cc"));
  EXPECT_THAT(str, HasSubstr("100"));
#else
  EXPECT_THAT(str, HasSubstr("(myfile.cc:100)"));
#endif
  LogMessage::RemoveLogToStream(&stream);
}

#if defined(WEBRTC_ANDROID)
TEST(LogTest, CheckTagAddedToStringInDefaultOnLogMessageAndroid) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  EXPECT_EQ(LS_INFO, LogMessage::GetLogToStream(&stream));

  RTC_LOG_TAG(LS_INFO, "my_tag") << "INFO";
  EXPECT_THAT(str, HasSubstr("INFO"));
  EXPECT_THAT(str, HasSubstr("my_tag"));
}
#endif

// Test the time required to write 1000 80-character logs to a string.
TEST(LogTest, Perf) {
  // This test should probably be turned into a benchmark.
  Clock& clock = *Clock::GetRealTimeClock();
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_VERBOSE);

  const std::string message(80, 'X');
  {
    LogMessageForTesting sanity_check_msg(__FILE__, __LINE__, LS_VERBOSE);
  }

  // We now know how many bytes the logging framework will tag onto every msg.
  const size_t logging_overhead = str.size();
  // Reset the stream to 0 size.
  str.clear();
  str.reserve(120000);
  static const int kRepetitions = 1000;

  Timestamp start = clock.CurrentTime();
  for (int i = 0; i < kRepetitions; ++i) {
    LogMessageForTesting(__FILE__, __LINE__, LS_VERBOSE).stream() << message;
  }
  Timestamp finish = clock.CurrentTime();

  LogMessage::RemoveLogToStream(&stream);

  EXPECT_EQ(str.size(), (message.size() + logging_overhead) * kRepetitions);
  RTC_LOG(LS_INFO) << "Total log time: " << (finish - start)
                   << " total bytes logged: " << str.size();
}

TEST(LogTest, EnumsAreSupported) {
  enum class TestEnum { kValue0 = 0, kValue1 = 1 };
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  RTC_LOG(LS_INFO) << "[" << TestEnum::kValue0 << "]";
  EXPECT_THAT(str, HasSubstr("[0]"));
  EXPECT_THAT(str, Not(HasSubstr("[1]")));
  RTC_LOG(LS_INFO) << "[" << TestEnum::kValue1 << "]";
  EXPECT_THAT(str, HasSubstr("[1]"));
  LogMessage::RemoveLogToStream(&stream);
}

TEST(LogTest, NoopSeverityDoesNotRunStringFormatting) {
  if (!LogMessage::IsNoop(LS_VERBOSE)) {
    RTC_LOG(LS_WARNING) << "Skipping test since verbose logging is turned on.";
    return;
  }
  bool was_called = false;
  auto cb = [&was_called]() {
    was_called = true;
    return "This could be an expensive callback.";
  };
  RTC_LOG(LS_VERBOSE) << "This should not be logged: " << cb();
  EXPECT_FALSE(was_called);
}

struct StructWithStringfy {
  template <typename Sink>
  friend void AbslStringify(Sink& sink, const StructWithStringfy& /*self*/) {
    sink.Append("absl-stringify");
  }
};

TEST(LogTest, UseAbslStringForCustomTypes) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  StructWithStringfy t;

  RTC_LOG(LS_INFO) << t;

  EXPECT_THAT(str, HasSubstr("absl-stringify"));

  LogMessage::RemoveLogToStream(&stream);
}

enum class TestEnumStringify { kValue0 = 0, kValue1 = 1 };

template <typename Sink>
void AbslStringify(Sink& sink, TestEnumStringify value) {
  switch (value) {
    case TestEnumStringify::kValue0:
      sink.Append("kValue0");
      break;
    case TestEnumStringify::kValue1:
      sink.Append("kValue1");
      break;
  }
}

TEST(LogTest, EnumSupportsAbslStringify) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  RTC_LOG(LS_INFO) << "[" << TestEnumStringify::kValue0 << "]";
  EXPECT_THAT(str, HasSubstr("[kValue0]"));
  EXPECT_THAT(str, Not(HasSubstr("[kValue1]")));
  RTC_LOG(LS_INFO) << "[" << TestEnumStringify::kValue1 << "]";
  EXPECT_THAT(str, HasSubstr("[kValue1]"));
  LogMessage::RemoveLogToStream(&stream);
}

#if !defined(WEBRTC_CHROMIUM_BUILD)
// Logging initialization tests require isolation because they modify global
// state that can only be set once per process. We use EXPECT_EXIT to run
// them in a forked child process.

#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS)
TEST(LogTest, ExplicitInitialization) {
  GTEST_FLAG_SET(death_test_style, "threadsafe");
#if defined(WEBRTC_WIN)
  _putenv_s("WEBRTC_TEST_SKIP_LOGGING_INIT", "1");
#else
  setenv("WEBRTC_TEST_SKIP_LOGGING_INIT", "1", 1);
#endif
  EXPECT_EXIT(
      {
        LoggingConfig config;
        config.set_min_severity(LS_WARNING);
        config.set_log_prefix("TEST_PREFIX: ");
        bool success = InitializeLogging(std::move(config));
        if (!success) {
          exit(1);
        }

        if (GetLoggingConfig().min_severity() != LS_WARNING) {
          exit(2);
        }

        RTC_LOG(LS_WARNING) << "Test message";
        exit(0);
      },
      ::testing::ExitedWithCode(0), "TEST_PREFIX: .*Test message");
#if defined(WEBRTC_WIN)
  _putenv_s("WEBRTC_TEST_SKIP_LOGGING_INIT", "");
#else
  unsetenv("WEBRTC_TEST_SKIP_LOGGING_INIT");
#endif
}

TEST(LogTest, ImplicitInitialization) {
  GTEST_FLAG_SET(death_test_style, "threadsafe");
  EXPECT_EXIT(
      {
        RTC_LOG(LS_WARNING) << "Trigger implicit init";
        LoggingConfig config;
        if (InitializeLogging(std::move(config))) {
          exit(1);
        }
        exit(0);
      },
      ::testing::ExitedWithCode(0), "");
}

TEST(LogTest, DoubleExplicitInitialization) {
  GTEST_FLAG_SET(death_test_style, "threadsafe");
#if defined(WEBRTC_WIN)
  _putenv_s("WEBRTC_TEST_SKIP_LOGGING_INIT", "1");
#else
  setenv("WEBRTC_TEST_SKIP_LOGGING_INIT", "1", 1);
#endif
  EXPECT_EXIT(
      {
        LoggingConfig config1;
        if (!InitializeLogging(std::move(config1))) {
          exit(1);
        }

        LoggingConfig config2;
        if (InitializeLogging(std::move(config2))) {
          exit(2);
        }

        exit(0);
      },
      ::testing::ExitedWithCode(0), "");
#if defined(WEBRTC_WIN)
  _putenv_s("WEBRTC_TEST_SKIP_LOGGING_INIT", "");
#else
  unsetenv("WEBRTC_TEST_SKIP_LOGGING_INIT");
#endif
}

TEST(LogTest, InitializeLoggingTransfersQueueName) {
  GTEST_FLAG_SET(death_test_style, "threadsafe");
#if defined(WEBRTC_WIN)
  _putenv_s("WEBRTC_TEST_SKIP_LOGGING_INIT", "1");
#else
  setenv("WEBRTC_TEST_SKIP_LOGGING_INIT", "1", 1);
#endif
  EXPECT_EXIT(
      {
        LoggingConfig config;
        config.set_log_queue_name(true);

        struct CustomSink : public LogSink {
          void OnLogMessage(const LogLineRef& line) override {
            queue_name = std::string(line.queue_name());
          }
          void OnLogMessage(const std::string& message) override {}
          void OnLogMessage(absl::string_view message) override {}
          std::string queue_name;
        };

        auto sink = std::make_unique<CustomSink>();
        CustomSink* sink_ptr = sink.get();
        config.AddSink(std::move(sink));

        if (!InitializeLogging(std::move(config))) {
          exit(2);
        }

        std::unique_ptr<Thread> thread = Thread::Create();
        thread->SetName("TestQueue", nullptr);
        thread->Start();

        thread->BlockingCall([&]() { RTC_LOG(LS_INFO) << "Hello"; });

        if (sink_ptr->queue_name != "TestQueue") {
          exit(1);
        }
        exit(0);
      },
      ::testing::ExitedWithCode(0), "");
#if defined(WEBRTC_WIN)
  _putenv_s("WEBRTC_TEST_SKIP_LOGGING_INIT", "");
#else
  unsetenv("WEBRTC_TEST_SKIP_LOGGING_INIT");
#endif
}

#endif  // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) &&
        // !defined(WEBRTC_IOS)

TEST(LogTest, LogQueueNameFromThread) {
  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  LogMessage::SetLogQueueNames(true);

  std::unique_ptr<Thread> thread = Thread::Create();
  thread->SetName("TName", nullptr);
  thread->Start();
  thread->BlockingCall([&]() { RTC_LOG(LS_INFO) << "Hello"; });

  EXPECT_THAT(str, HasSubstr("[TName]"));

  LogMessage::SetLogQueueNames(false);  // Reset
  LogMessage::RemoveLogToStream(&stream);
}

class LogTestWithParam : public testing::TestWithParam<bool> {};

TEST_P(LogTestWithParam, LogQueueNameFromTaskQueueOverridingThread) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  bool prev_log_threads = LogMessage::LogThreads(GetParam());
#pragma clang diagnostic pop
  bool prev_log_queue_names = LogMessage::SetLogQueueNames(true);

  std::string str;
  LogSinkImpl stream(&str);
  LogMessage::AddLogToStream(&stream, LS_INFO);
  absl::Cleanup cleanup = [&] {
    LogMessage::RemoveLogToStream(&stream);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    LogMessage::LogThreads(prev_log_threads);
#pragma clang diagnostic pop
    LogMessage::SetLogQueueNames(prev_log_queue_names);
  };

  std::unique_ptr<Thread> thread = Thread::Create();
  thread->SetName("TName", nullptr);
  thread->Start();

  class CustomTaskQueue : public TaskQueueBase {
   public:
    explicit CustomTaskQueue(absl::string_view name) : name_(name) {}
    void Delete() override {}
    void PostTaskImpl(absl::AnyInvocable<void() &&> task,
                      const PostTaskTraits& traits,
                      const Location& location) override {
      CurrentTaskQueueSetter set_current(this);
      std::move(task)();
    }
    void PostDelayedTaskImpl(absl::AnyInvocable<void() &&> task,
                             TimeDelta delay,
                             const PostDelayedTaskTraits& traits,
                             const Location& location) override {
      RTC_DCHECK_NOTREACHED();
    }
    absl::string_view queue_name() const override { return name_; }

   private:
    std::string name_;
  };

  thread->BlockingCall([&]() {
    // 1. Verify thread name is printed first.
    RTC_LOG(LS_INFO) << "Prints the name of the thread.";
    EXPECT_THAT(str, HasSubstr("TName]"));
    str.clear();

    // 2. Set custom task queue.
    CustomTaskQueue custom_tq("QName");
    custom_tq.PostTask(
        [&]() { RTC_LOG(LS_INFO) << "Prints the name of the task queue."; });
    EXPECT_THAT(str, HasSubstr("QName]"));
    EXPECT_THAT(str, Not(HasSubstr("TName]")));
    str.clear();

    // 3. Verify fallback to thread name.
    RTC_LOG(LS_INFO) << "Prints the name of the thread again.";
    EXPECT_THAT(str, HasSubstr("TName]"));
  });
}

INSTANTIATE_TEST_SUITE_P(All, LogTestWithParam, ::testing::Bool());
#endif  // !defined(WEBRTC_CHROMIUM_BUILD)

}  // namespace webrtc
#endif  // RTC_LOG_ENABLED()
