// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Note: this test tests RTC_LOG_V and RTC_LOG_E since all other logs are
// expressed in forms of them. RTC_LOG is also tested for good measure.
// Also note that we are only allowed to call InitLogging() twice so the test
// cases are more dense than normal.

// We must include Chromium headers before including the overrides header
// since webrtc's logging.h file may conflict with chromium.

#include "base/logging.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc_overrides/rtc_base/logging.h"

namespace {

static const int kDefaultVerbosity = 0;

static const char* AsString(webrtc::LoggingSeverity severity) {
  switch (severity) {
    case webrtc::LS_ERROR:
      return "LS_ERROR";
    case webrtc::LS_WARNING:
      return "LS_WARNING";
    case webrtc::LS_INFO:
      return "LS_INFO";
    case webrtc::LS_VERBOSE:
      return "LS_VERBOSE";
    case webrtc::LS_SENSITIVE:
      return "LS_SENSITIVE";
    default:
      return "";
  }
}

class WebRtcTextLogTest : public testing::Test {
 public:
  void SetUp() override {
    // Some builds don't have runtime vlogging. See base/logging.h.
    if (!VLOG_IS_ON(0)) {
      GTEST_SKIP();
    }

    ASSERT_TRUE(log_dir_.CreateUniqueTempDir());
    log_file_path_ = log_dir_.GetPath().AppendASCII("webrtc_log");
  }

 protected:
  bool Initialize(int verbosity_level) {
    // The command line flags are parsed here and the log file name is set.
    logging::LoggingSettings settings;
    settings.logging_dest = logging::LOG_TO_FILE;
    settings.log_file_path = log_file_path_.value().data();
    settings.lock_log = logging::DONT_LOCK_LOG_FILE;
    settings.delete_old = logging::DELETE_OLD_LOG_FILE;
    if (!logging::InitLogging(settings)) {
      return false;
    }
    logging::SetMinLogLevel(-verbosity_level);

    EXPECT_TRUE(VLOG_IS_ON(verbosity_level));

    EXPECT_FALSE(VLOG_IS_ON(verbosity_level + 1));
    return true;
  }

  base::ScopedTempDir log_dir_;
  base::FilePath log_file_path_;
};

TEST_F(WebRtcTextLogTest, DefaultConfiguration) {
  ASSERT_TRUE(Initialize(kDefaultVerbosity));

  // In the default configuration only warnings and errors should be logged.
  RTC_LOG_V(webrtc::LS_ERROR) << AsString(webrtc::LS_ERROR);
  RTC_LOG_V(webrtc::LS_WARNING) << AsString(webrtc::LS_WARNING);
  RTC_LOG_V(webrtc::LS_INFO) << AsString(webrtc::LS_INFO);
  RTC_LOG_V(webrtc::LS_VERBOSE) << AsString(webrtc::LS_VERBOSE);
  RTC_LOG_V(webrtc::LS_SENSITIVE) << AsString(webrtc::LS_SENSITIVE);

  // Read file to string.
  std::string contents_of_file;
  base::ReadFileToString(log_file_path_, &contents_of_file);

  // Make sure string contains the expected values.
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_ERROR)));
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_WARNING)));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr(AsString(webrtc::LS_INFO))));
  EXPECT_THAT(
      contents_of_file,
      ::testing::Not(::testing::HasSubstr(AsString(webrtc::LS_VERBOSE))));
  EXPECT_THAT(
      contents_of_file,
      ::testing::Not(::testing::HasSubstr(AsString(webrtc::LS_SENSITIVE))));
}

TEST_F(WebRtcTextLogTest, InfoConfiguration) {
  ASSERT_TRUE(Initialize(0));  // 0 == Chrome's 'info' level.

  // In this configuration everything lower or equal to LS_INFO should be
  // logged.
  RTC_LOG_V(webrtc::LS_ERROR) << AsString(webrtc::LS_ERROR);
  RTC_LOG_V(webrtc::LS_WARNING) << AsString(webrtc::LS_WARNING);
  RTC_LOG_V(webrtc::LS_INFO) << AsString(webrtc::LS_INFO);
  RTC_LOG_V(webrtc::LS_VERBOSE) << AsString(webrtc::LS_VERBOSE);
  RTC_LOG_V(webrtc::LS_SENSITIVE) << AsString(webrtc::LS_SENSITIVE);

  // Read file to string.
  std::string contents_of_file;
  base::ReadFileToString(log_file_path_, &contents_of_file);

  // Make sure string contains the expected values.
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_ERROR)));
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_WARNING)));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr(AsString(webrtc::LS_INFO))));
  EXPECT_THAT(
      contents_of_file,
      ::testing::Not(::testing::HasSubstr(AsString(webrtc::LS_VERBOSE))));
  EXPECT_THAT(
      contents_of_file,
      ::testing::Not(::testing::HasSubstr(AsString(webrtc::LS_SENSITIVE))));

  // Also check that the log is proper.
  EXPECT_THAT(contents_of_file, ::testing::HasSubstr("logging_unittest.cc"));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr("logging.h")));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr("logging.cc")));
}

TEST_F(WebRtcTextLogTest, LogEverythingConfiguration) {
  ASSERT_TRUE(Initialize(2));  // verbosity at level 2 allows LS_SENSITIVE.

  // In this configuration everything should be logged.
  RTC_LOG_V(webrtc::LS_ERROR) << AsString(webrtc::LS_ERROR);
  RTC_LOG_V(webrtc::LS_WARNING) << AsString(webrtc::LS_WARNING);
  RTC_LOG(LS_INFO) << AsString(webrtc::LS_INFO);
  static const int kFakeError = 1;
  RTC_LOG_E(LS_INFO, EN, kFakeError)
      << "RTC_LOG_E(" << AsString(webrtc::LS_INFO) << ")";
  RTC_LOG_V(webrtc::LS_VERBOSE) << AsString(webrtc::LS_VERBOSE);
  RTC_LOG_V(webrtc::LS_SENSITIVE) << AsString(webrtc::LS_SENSITIVE);

  // Read file to string.
  std::string contents_of_file;
  base::ReadFileToString(log_file_path_, &contents_of_file);

  // Make sure string contains the expected values.
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_ERROR)));
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_WARNING)));

  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_INFO)));
  // RTC_LOG_E
  EXPECT_THAT(contents_of_file, ::testing::HasSubstr(strerror(kFakeError)));
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_VERBOSE)));
  EXPECT_THAT(contents_of_file,
              ::testing::HasSubstr(AsString(webrtc::LS_SENSITIVE)));
}

TEST_F(WebRtcTextLogTest, LogIf) {
  ASSERT_TRUE(Initialize(2));

  RTC_LOG_IF(LS_INFO, true) << "IfTrue";
  RTC_LOG_IF(LS_INFO, false) << "IfFalse";
  RTC_LOG_IF_F(LS_INFO, true) << "LogF";
  RTC_LOG_IF_F(LS_INFO, false) << "NoLogF";

  RTC_DLOG_IF(LS_INFO, true) << "DebugIfTrue";
  RTC_DLOG_IF(LS_INFO, false) << "DebugIfFalse";
  RTC_DLOG_IF_F(LS_INFO, true) << "DebugLogF";
  RTC_DLOG_IF_F(LS_INFO, false) << "DebugNotLogF";

  // Read file to string.
  std::string contents_of_file;
  base::ReadFileToString(log_file_path_, &contents_of_file);

  EXPECT_THAT(contents_of_file, ::testing::HasSubstr("IfTrue"));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr("IfFalse")));
  EXPECT_THAT(contents_of_file, ::testing::HasSubstr(__FUNCTION__));
  EXPECT_THAT(contents_of_file, ::testing::HasSubstr("LogF"));
  EXPECT_THAT(contents_of_file, ::testing::Not(::testing::HasSubstr("NoLogF")));

#if RTC_DLOG_IS_ON
  EXPECT_THAT(contents_of_file, ::testing::HasSubstr("DebugIfTrue"));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr("DebugIfFalse")));
  EXPECT_THAT(contents_of_file, ::testing::HasSubstr("DebugLogF"));
  EXPECT_THAT(contents_of_file,
              ::testing::Not(::testing::HasSubstr("DebugNoLogF")));
#endif  // RTC_DLOG_IF_ON
}

}  // namespace
