// Copyright 2020 The Pigweed Authors
//
// 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
//
//     https://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 "pw_log_multisink/log_queue.h"

#include "gtest/gtest.h"
#include "pw_log/levels.h"
#include "pw_log/proto/log.pwpb.h"
#include "pw_protobuf/decoder.h"

namespace pw::log_rpc {
namespace {

constexpr size_t kEncodeBufferSize = 512;

constexpr const char kTokenizedMessage[] = "msg_token";
constexpr uint32_t kFlags = 0xF;
constexpr uint32_t kLevel = 0b010;
constexpr uint32_t kLine = 0b101011000;
constexpr uint32_t kTokenizedThread = 0xF;
constexpr int64_t kTimestamp = 0;

constexpr size_t kLogBufferSize = kEncodeBufferSize * 3;

void VerifyLogEntry(pw::protobuf::Decoder& log_decoder,
                    const char* expected_tokenized_message,
                    const uint32_t expected_flags,
                    const uint32_t expected_level,
                    const uint32_t expected_line,
                    const uint32_t /* expected_tokenized_thread */,
                    const int64_t expected_timestamp) {
  ConstByteSpan log_entry_message;
  EXPECT_TRUE(log_decoder.Next().ok());  // preamble
  EXPECT_EQ(1U, log_decoder.FieldNumber());
  EXPECT_TRUE(log_decoder.ReadBytes(&log_entry_message).ok());

  pw::protobuf::Decoder entry_decoder(log_entry_message);
  ConstByteSpan tokenized_message;
  EXPECT_TRUE(entry_decoder.Next().ok());  // tokenized_message
  EXPECT_EQ(1U, entry_decoder.FieldNumber());
  EXPECT_TRUE(entry_decoder.ReadBytes(&tokenized_message).ok());
  EXPECT_TRUE(std::memcmp(tokenized_message.begin(),
                          (const void*)expected_tokenized_message,
                          tokenized_message.size()) == 0);

  uint32_t line_level;
  EXPECT_TRUE(entry_decoder.Next().ok());  // line_level
  EXPECT_EQ(2U, entry_decoder.FieldNumber());
  EXPECT_TRUE(entry_decoder.ReadUint32(&line_level).ok());
  EXPECT_EQ(expected_level, line_level & PW_LOG_LEVEL_BITMASK);
  EXPECT_EQ(expected_line,
            (line_level & ~PW_LOG_LEVEL_BITMASK) >> PW_LOG_LEVEL_BITS);

  uint32_t flags;
  EXPECT_TRUE(entry_decoder.Next().ok());  // flags
  EXPECT_EQ(3U, entry_decoder.FieldNumber());
  EXPECT_TRUE(entry_decoder.ReadUint32(&flags).ok());
  EXPECT_EQ(expected_flags, flags);

  // TODO(prashanthsw): Add thread name when supported.
  // uint32_t tokenized_thread;
  // EXPECT_TRUE(entry_decoder.Next().ok());  // tokenized_thread
  // EXPECT_EQ(4U, entry_decoder.FieldNumber());
  // EXPECT_TRUE(entry_decoder.ReadUint32(&tokenized_thread).ok());
  // EXPECT_EQ(expected_tokenized_thread, tokenized_thread);

  int64_t timestamp;
  EXPECT_TRUE(entry_decoder.Next().ok());  // timestamp
  EXPECT_EQ(4U, entry_decoder.FieldNumber());
  EXPECT_TRUE(entry_decoder.ReadInt64(&timestamp).ok());
  EXPECT_EQ(expected_timestamp, timestamp);
}

}  // namespace

TEST(LogQueue, SinglePushPopTokenizedMessage) {
  std::byte log_buffer[kLogBufferSize];
  LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);

  EXPECT_EQ(OkStatus(),
            log_queue.PushTokenizedMessage(
                std::as_bytes(std::span(kTokenizedMessage)),
                kFlags,
                kLevel,
                kLine,
                kTokenizedThread,
                kTimestamp));

  std::byte log_entry[kEncodeBufferSize];
  Result<LogEntries> pop_result = log_queue.Pop(std::span(log_entry));
  EXPECT_TRUE(pop_result.ok());

  pw::protobuf::Decoder log_decoder(pop_result.value().entries);
  EXPECT_EQ(pop_result.value().entry_count, 1U);
  VerifyLogEntry(log_decoder,
                 kTokenizedMessage,
                 kFlags,
                 kLevel,
                 kLine,
                 kTokenizedThread,
                 kTimestamp);
}

TEST(LogQueue, MultiplePushPopTokenizedMessage) {
  constexpr size_t kEntryCount = 3;

  std::byte log_buffer[1024];
  LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);

  for (size_t i = 0; i < kEntryCount; i++) {
    EXPECT_EQ(OkStatus(),
              log_queue.PushTokenizedMessage(
                  std::as_bytes(std::span(kTokenizedMessage)),
                  kFlags,
                  kLevel,
                  kLine + (i << 3),
                  kTokenizedThread,
                  kTimestamp + i));
  }

  std::byte log_entry[kEncodeBufferSize];
  for (size_t i = 0; i < kEntryCount; i++) {
    Result<LogEntries> pop_result = log_queue.Pop(std::span(log_entry));
    EXPECT_TRUE(pop_result.ok());

    pw::protobuf::Decoder log_decoder(pop_result.value().entries);
    EXPECT_EQ(pop_result.value().entry_count, 1U);
    VerifyLogEntry(log_decoder,
                   kTokenizedMessage,
                   kFlags,
                   kLevel,
                   kLine + (i << 3),
                   kTokenizedThread,
                   kTimestamp + i);
  }
}

TEST(LogQueue, PopMultiple) {
  constexpr size_t kEntryCount = 3;

  std::byte log_buffer[kLogBufferSize];
  LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue(log_buffer);

  for (size_t i = 0; i < kEntryCount; i++) {
    EXPECT_EQ(OkStatus(),
              log_queue.PushTokenizedMessage(
                  std::as_bytes(std::span(kTokenizedMessage)),
                  kFlags,
                  kLevel,
                  kLine + (i << 3),
                  kTokenizedThread,
                  kTimestamp + i));
  }

  std::byte log_entries[kLogBufferSize];
  Result<LogEntries> pop_result = log_queue.PopMultiple(log_entries);
  EXPECT_TRUE(pop_result.ok());

  pw::protobuf::Decoder log_decoder(pop_result.value().entries);
  EXPECT_EQ(pop_result.value().entry_count, kEntryCount);
  for (size_t i = 0; i < kEntryCount; i++) {
    VerifyLogEntry(log_decoder,
                   kTokenizedMessage,
                   kFlags,
                   kLevel,
                   kLine + (i << 3),
                   kTokenizedThread,
                   kTimestamp + i);
  }
}

TEST(LogQueue, TooSmallEncodeBuffer) {
  constexpr size_t kSmallBuffer = 1;

  std::byte log_buffer[kLogBufferSize];
  LogQueueWithEncodeBuffer<kSmallBuffer> log_queue(log_buffer);
  EXPECT_EQ(Status::Internal(),
            log_queue.PushTokenizedMessage(
                std::as_bytes(std::span(kTokenizedMessage)),
                kFlags,
                kLevel,
                kLine,
                kTokenizedThread,
                kTimestamp));
}

TEST(LogQueue, TooSmallLogBuffer) {
  constexpr size_t kSmallerThanPreamble = 1;
  constexpr size_t kEntryCount = 100;

  // Expect OUT_OF_RANGE when the buffer is smaller than a preamble.
  std::byte log_buffer[kLogBufferSize];
  LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue_small(
      std::span(log_buffer, kSmallerThanPreamble));
  EXPECT_EQ(Status::OutOfRange(),
            log_queue_small.PushTokenizedMessage(
                std::as_bytes(std::span(kTokenizedMessage)),
                kFlags,
                kLevel,
                kLine,
                kTokenizedThread,
                kTimestamp));

  // Expect RESOURCE_EXHAUSTED when there's not enough space for the chunk.
  LogQueueWithEncodeBuffer<kEncodeBufferSize> log_queue_medium(log_buffer);
  for (size_t i = 0; i < kEntryCount; i++) {
    log_queue_medium.PushTokenizedMessage(
        std::as_bytes(std::span(kTokenizedMessage)),
        kFlags,
        kLevel,
        kLine,
        kTokenizedThread,
        kTimestamp);
  }
  EXPECT_EQ(Status::ResourceExhausted(),
            log_queue_medium.PushTokenizedMessage(
                std::as_bytes(std::span(kTokenizedMessage)),
                kFlags,
                kLevel,
                kLine,
                kTokenizedThread,
                kTimestamp));
}

}  // namespace pw::log_rpc
