/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "perfetto/base/logging.h"

#include <stdint.h>

#include <condition_variable>
#include <mutex>
#include <thread>
#include <vector>

#include "perfetto/ext/base/crash_keys.h"
#include "perfetto/ext/base/string_utils.h"
#include "src/base/log_ring_buffer.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace base {
namespace {

char g_last_line[256];

TEST(LoggingTest, Basic) {
  SetLogMessageCallback(nullptr);
  LogMessage(kLogDebug, "file.cc", 100, "test message %d", 1);

  SetLogMessageCallback(+[](LogMessageCallbackArgs log) {
    sprintf(g_last_line, "%d:%s:%d:%s", log.level, log.filename, log.line,
            log.message);
  });

  g_last_line[0] = 0;
  LogMessage(kLogDebug, "file.cc", 101, "test message %d", 2);
  ASSERT_STREQ(g_last_line, "0:file.cc:101:test message 2");

  g_last_line[0] = 0;
  SetLogMessageCallback(nullptr);
  LogMessage(kLogDebug, "file.cc", 102, "test message %d", 3);
  ASSERT_STREQ(g_last_line, "");
}

TEST(LogRingBufferTest, SimpleCases) {
  char buf[4096];
  memset(buf, 'x', sizeof(buf));  // Deliberately not 0-initialized.

  LogRingBuffer lrb;
  EXPECT_EQ(0u, lrb.Read(buf, sizeof(buf)));
  EXPECT_STREQ(buf, "");

  // Append one entry and read back.
  lrb.Append("tstamp1,", "src1.cc", "message1");
  EXPECT_EQ(25u, lrb.Read(buf, sizeof(buf)));
  EXPECT_STREQ(buf, "tstamp1,src1.cc message1\n");

  lrb.Append("tstamp2,", "src2.cc", "message2");
  EXPECT_EQ(50u, lrb.Read(buf, sizeof(buf)));
  EXPECT_STREQ(buf, "tstamp1,src1.cc message1\ntstamp2,src2.cc message2\n");
}

TEST(LogRingBufferTest, Truncation) {
  // Append a long entry that overflows the event slot.
  std::string long_msg;
  long_msg.resize(kLogRingBufMsgLen * 2);
  for (size_t i = 0; i < long_msg.size(); i++)
    long_msg[i] = static_cast<char>('a' + (i % 27));
  LogRingBuffer lrb;
  lrb.Append("A", "B", StringView(long_msg));

  // Check that it gets truncated with no side effects.
  char buf[4096];
  memset(buf, 'x', sizeof(buf));  // Deliberately not 0-initialized.
  auto expected = "AB " + long_msg.substr(0, kLogRingBufMsgLen - 4) + "\n";
  EXPECT_EQ(expected.size(), lrb.Read(buf, sizeof(buf)));
  EXPECT_EQ(buf, expected);

  // Append a short message and check everything still works.
  lrb.Append("X", "Y", "foo");
  EXPECT_EQ(expected.size() + 7, lrb.Read(buf, sizeof(buf)));
  EXPECT_EQ(buf, expected + "XY foo\n");
}

TEST(LogRingBufferTest, Wrapping) {
  LogRingBuffer lrb;

  std::vector<std::string> expected_logs;
  for (uint32_t i = 0; i < 128; i++) {
    std::string id = std::to_string(i);
    std::string tstamp = "tstamp" + id + ",";
    std::string src = "src";
    std::string msg;
    msg.resize(1 + (i % 16));
    for (size_t c = 0; c < msg.size(); c++)
      msg[c] = static_cast<char>('a' + c);
    lrb.Append(StringView(tstamp), StringView(src), StringView(msg));
    auto expected_log =
        (tstamp + src + " " + msg).substr(0, kLogRingBufMsgLen) + "\n";
    expected_logs.emplace_back(expected_log);
  }

  std::string expected;
  for (size_t i = expected_logs.size() - kLogRingBufEntries;
       i < expected_logs.size(); i++) {
    expected += expected_logs[i];
  }

  char buf[kLogRingBufMsgLen * kLogRingBufEntries];
  memset(buf, 'x', sizeof(buf));  // Deliberately not 0-initialized.
  lrb.Read(buf, sizeof(buf));
  EXPECT_EQ(buf, expected);

  // Do a partial readback which will cause output truncation.
  lrb.Read(buf, 127);
  EXPECT_EQ(buf, expected.substr(0, 127 - 1));  // - 1 for the NUL terminator.
}

// Writes concurrently into the ring buffer and check that all the events are
// seen in some order.
TEST(LogRingBufferTest, MultiThreadedWrites) {
  LogRingBuffer lrb;

  std::vector<std::thread> threads;
  const size_t kNumThreads = 8;

  std::mutex mutex;
  std::condition_variable cond;
  bool sync_start = false;

  auto thread_main = [&](size_t thread_idx) {
    std::unique_lock<std::mutex> lock(mutex);
    cond.wait(lock, [&] { return sync_start; });

    std::string tstamp = "ts" + std::to_string(thread_idx) + ",";
    std::string src = "src";
    std::string msg(thread_idx + 1, '.');  // A variable number of dots.
    lrb.Append(StringView(tstamp), StringView(src), StringView(msg));
  };

  std::vector<std::string> expected_events;
  for (size_t i = 0; i < kNumThreads; i++) {
    threads.emplace_back(thread_main, i);
    std::string id = std::to_string(i);
    expected_events.emplace_back("ts" + id + ",src " + std::string(i + 1, '.'));
  }

  // Unlock all the threads as close as possible to maximize races.
  {
    std::unique_lock<std::mutex> lock(mutex);
    sync_start = true;
    cond.notify_all();
  }

  for (auto& thread : threads)
    thread.join();

  char buf[kLogRingBufEntries * 40];
  memset(buf, 'x', sizeof(buf));  // Deliberately not 0-initialized.
  lrb.Read(buf, sizeof(buf));

  std::vector<std::string> actual_events = SplitString(buf, "\n");
  EXPECT_THAT(actual_events,
              testing::UnorderedElementsAreArray(expected_events));
}

TEST(CrashKeysTest, SetClearAndLongKeys) {
  UnregisterAllCrashKeysForTesting();

  char buf[1024];
  memset(buf, 'x', sizeof(buf));
  EXPECT_EQ(0u, SerializeCrashKeys(buf, sizeof(buf)));
  EXPECT_STREQ(buf, "");

  CrashKey k1("key1");
  CrashKey k2("key2");
  CrashKey k3("key3");
  CrashKey k4("key4");

  k1.Set(0);
  k1.Clear();

  k2.Set(42);

  k3.Set("xx");
  k3.Clear();

  k4.Set("value");

  EXPECT_EQ(21u, SerializeCrashKeys(buf, sizeof(buf)));
  EXPECT_STREQ(buf, "key2: 42\nkey4: value\n");

  EXPECT_EQ(0u, SerializeCrashKeys(buf, 0));

  EXPECT_EQ(0u, SerializeCrashKeys(buf, 1));
  EXPECT_STREQ(buf, "");

  // Test truncated output.
  EXPECT_EQ(5u, SerializeCrashKeys(buf, 5 + 1));
  EXPECT_STREQ(buf, "key2:");

  k2.Clear();

  std::string long_str(1024, 'x');
  k4.Set(StringView(long_str));

  EXPECT_EQ(6 + kCrashKeyMaxStrSize, SerializeCrashKeys(buf, sizeof(buf)));
  std::string expected =
      "key4: " + long_str.substr(0, kCrashKeyMaxStrSize - 1) + "\n";
  EXPECT_EQ(buf, expected);

  UnregisterAllCrashKeysForTesting();
}

TEST(CrashKeysTest, ScopedSet) {
  UnregisterAllCrashKeysForTesting();

  char buf[1024];
  memset(buf, 'x', sizeof(buf));

  CrashKey k1("key1");
  CrashKey k2("key2");

  auto scoped_key = k1.SetScoped(42);
  EXPECT_GT(SerializeCrashKeys(buf, sizeof(buf)), 0u);
  EXPECT_STREQ(buf, "key1: 42\n");

  {
    auto scoped_key2 = k2.SetScoped("foo");
    EXPECT_GT(SerializeCrashKeys(buf, sizeof(buf)), 0u);
    EXPECT_STREQ(buf, "key1: 42\nkey2: foo\n");
  }

  EXPECT_GT(SerializeCrashKeys(buf, sizeof(buf)), 0u);
  EXPECT_STREQ(buf, "key1: 42\n");

  k1.Clear();
  EXPECT_EQ(0u, SerializeCrashKeys(buf, sizeof(buf)));
  EXPECT_STREQ(buf, "");

  UnregisterAllCrashKeysForTesting();
}

}  // namespace
}  // namespace base
}  // namespace perfetto
