// 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.

#define PW_TRACE_MODULE_NAME "TST"

#include "pw_trace_tokenized/trace_buffer.h"

#include "gtest/gtest.h"
#include "pw_trace/trace.h"

TEST(TokenizedTrace, Simple) {
  PW_TRACE_SET_ENABLED(true);
  pw::trace::ClearBuffer();

  PW_TRACE_INSTANT("Test");

  // Check results
  pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();

  EXPECT_EQ(buf->EntryCount(), 1u);
  const size_t expected_min_bytes_used =
      1 /*varint size */ + 4 /*token*/ + 1 /* min varint time */;
  const size_t expected_max_bytes_used = 1 /*varint size */ + 4 /*token*/ +
                                         sizeof(PW_TRACE_TIME_TYPE) +
                                         1 /* max varint time */;

  EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
  EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
}

TEST(TokenizedTrace, TraceId) {
  PW_TRACE_SET_ENABLED(true);
  pw::trace::ClearBuffer();

  uint32_t trace_id = 256;
  PW_TRACE_INSTANT("Test", "group", trace_id);

  // Check results
  pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();

  EXPECT_EQ(buf->EntryCount(), 1u);
  const size_t expected_min_bytes_used = 1 /*varint size */ + 4 /*token*/ +
                                         1 /* min varint time */ +
                                         2 /*varint trace id*/;
  const size_t expected_max_bytes_used =
      1 /*varint size */ + 4 /*token*/ + sizeof(PW_TRACE_TIME_TYPE) +
      1 /* max varint time */ + 2 /*varint trace id*/;

  EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
  EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);
}

TEST(TokenizedTrace, Data) {
  PW_TRACE_SET_ENABLED(true);
  pw::trace::ClearBuffer();

  char data[] = "some test data";
  PW_TRACE_INSTANT_DATA("Test", "test_data", data, sizeof(data));

  // Check results
  pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();

  EXPECT_EQ(buf->EntryCount(), 1u);
  const size_t expected_min_bytes_used =
      1 /*varint size */ + 4 /*token*/ + 1 /* min varint time */ + sizeof(data);
  const size_t expected_max_bytes_used = 1 /*varint size */ + 4 /*token*/ +
                                         sizeof(PW_TRACE_TIME_TYPE) +
                                         1 /* max varint time */ + sizeof(data);

  EXPECT_GE(buf->TotalUsedBytes(), expected_min_bytes_used);
  EXPECT_LE(buf->TotalUsedBytes(), expected_max_bytes_used);

  std::byte value[expected_max_bytes_used];
  size_t bytes_read = 0;
  EXPECT_EQ(buf->PeekFront(std::span<std::byte>(value), &bytes_read),
            pw::Status::Ok());

  // read size is minus 1, since doesn't include varint size
  EXPECT_GE(bytes_read, expected_min_bytes_used - 1);
  EXPECT_LE(bytes_read, expected_max_bytes_used - 1);
  EXPECT_STREQ(data,
               reinterpret_cast<char*>(&value[bytes_read - sizeof(data)]));
}

TEST(TokenizedTrace, Clear) {
  PW_TRACE_SET_ENABLED(true);
  pw::trace::ClearBuffer();
  pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();

  PW_TRACE_INSTANT("Test");
  EXPECT_EQ(buf->EntryCount(), 1u);
  pw::trace::ClearBuffer();
  EXPECT_EQ(buf->EntryCount(), 0u);
}

TEST(TokenizedTrace, Overflow) {
  PW_TRACE_SET_ENABLED(true);
  pw::trace::ClearBuffer();
  pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();

  // Add samples until entry count stops increasing.
  uint32_t last_entry_count = 0;
  size_t count = 0;
  while (buf->EntryCount() == 0 || buf->EntryCount() > last_entry_count) {
    last_entry_count = buf->EntryCount();
    PW_TRACE_INSTANT_DATA("Test", "count", &count, sizeof(count));
    count++;
  }
  // CHECK
  size_t expected_count = 1;  // skip first (since it was lost)
  while (buf->EntryCount() > 0) {
    std::byte value[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
    size_t bytes_read = 0;
    EXPECT_EQ(buf->PeekFront(std::span<std::byte>(value), &bytes_read),
              pw::Status::Ok());
    EXPECT_EQ(buf->PopFront(), pw::Status::Ok());
    EXPECT_EQ(*reinterpret_cast<size_t*>(&value[bytes_read - sizeof(size_t)]),
              expected_count);
    expected_count++;
  }

  EXPECT_EQ(count, expected_count);
}

TEST(TokenizedTrace, BlockTooLarge) {
  PW_TRACE_SET_ENABLED(true);
  pw::trace::ClearBuffer();
  pw::ring_buffer::PrefixedEntryRingBuffer* buf = pw::trace::GetBuffer();
  uint8_t data[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
  PW_TRACE_INSTANT_DATA("Test", "data", data, sizeof(data));
  EXPECT_EQ(buf->EntryCount(), 0u);
}