/*
 * Copyright (C) 2023 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 "src/trace_processor/sorter/trace_token_buffer.h"

#include <optional>

#include "perfetto/base/compiler.h"
#include "perfetto/trace_processor/trace_blob.h"
#include "perfetto/trace_processor/trace_blob_view.h"
#include "src/trace_processor/importers/common/parser_types.h"
#include "src/trace_processor/importers/proto/packet_sequence_state.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace trace_processor {
namespace {

class TraceTokenBufferUnittest : public testing::Test {
 protected:
  TraceTokenBuffer store;
  TraceProcessorContext context;
  PacketSequenceState state{&context};
};

TEST_F(TraceTokenBufferUnittest, TracePacketDataInOut) {
  TraceBlobView tbv(TraceBlob::Allocate(1024));
  TracePacketData tpd{tbv.copy(), state.current_generation()};

  TraceTokenBuffer::Id id = store.Append(std::move(tpd));
  TracePacketData extracted = store.Extract<TracePacketData>(id);
  ASSERT_EQ(extracted.packet, tbv);
  ASSERT_EQ(extracted.sequence_state, state.current_generation());
}

TEST_F(TraceTokenBufferUnittest, PacketAppendMultipleBlobs) {
  TraceBlobView tbv_1(TraceBlob::Allocate(1024));
  TraceBlobView tbv_2(TraceBlob::Allocate(2048));
  TraceBlobView tbv_3(TraceBlob::Allocate(4096));

  TraceTokenBuffer::Id id_1 =
      store.Append(TracePacketData{tbv_1.copy(), state.current_generation()});
  TraceTokenBuffer::Id id_2 =
      store.Append(TracePacketData{tbv_2.copy(), state.current_generation()});
  ASSERT_EQ(store.Extract<TracePacketData>(id_1).packet, tbv_1);
  ASSERT_EQ(store.Extract<TracePacketData>(id_2).packet, tbv_2);

  TraceTokenBuffer::Id id_3 =
      store.Append(TracePacketData{tbv_3.copy(), state.current_generation()});
  ASSERT_EQ(store.Extract<TracePacketData>(id_3).packet, tbv_3);
}

TEST_F(TraceTokenBufferUnittest, BlobSharing) {
  TraceBlobView root(TraceBlob::Allocate(2048));
  TraceBlobView tbv_1 = root.slice_off(0, 1024);
  TraceBlobView tbv_2 = root.slice_off(1024, 512);
  TraceBlobView tbv_3 = root.slice_off(1536, 512);

  TraceTokenBuffer::Id id_1 =
      store.Append(TracePacketData{tbv_1.copy(), state.current_generation()});
  TraceTokenBuffer::Id id_2 =
      store.Append(TracePacketData{tbv_2.copy(), state.current_generation()});
  ASSERT_EQ(store.Extract<TracePacketData>(id_1).packet, tbv_1);
  ASSERT_EQ(store.Extract<TracePacketData>(id_2).packet, tbv_2);

  TraceTokenBuffer::Id id_3 =
      store.Append(TracePacketData{tbv_3.copy(), state.current_generation()});
  ASSERT_EQ(store.Extract<TracePacketData>(id_3).packet, tbv_3);
}

TEST_F(TraceTokenBufferUnittest, SequenceStateSharing) {
  TraceBlobView root(TraceBlob::Allocate(2048));
  TraceBlobView tbv_1 = root.slice_off(0, 1024);
  TraceBlobView tbv_2 = root.slice_off(1024, 512);

  TraceTokenBuffer::Id id_1 =
      store.Append(TracePacketData{tbv_1.copy(), state.current_generation()});
  TraceTokenBuffer::Id id_2 =
      store.Append(TracePacketData{tbv_2.copy(), state.current_generation()});
  ASSERT_EQ(store.Extract<TracePacketData>(id_1).sequence_state,
            state.current_generation());
  ASSERT_EQ(store.Extract<TracePacketData>(id_2).sequence_state,
            state.current_generation());
}

TEST_F(TraceTokenBufferUnittest, ManySequenceState) {
  TraceBlobView root(TraceBlob::Allocate(1024));

  std::array<TraceTokenBuffer::Id, 1024> ids;
  std::array<PacketSequenceStateGeneration*, 1024> refs;
  for (uint32_t i = 0; i < 1024; ++i) {
    refs[i] = state.current_generation().get();
    ids[i] = store.Append(
        TracePacketData{root.slice_off(i, 1), state.current_generation()});
    state.OnIncrementalStateCleared();
  }

  for (uint32_t i = 0; i < 1024; ++i) {
    ASSERT_EQ(refs[i],
              store.Extract<TracePacketData>(ids[i]).sequence_state.get());
  }
}

TEST_F(TraceTokenBufferUnittest, PacketLargeOffset) {
  TraceBlobView tbv(TraceBlob::Allocate(256ul * 1024));

  TraceBlobView slice_1 = tbv.slice_off(0, 1024ul);
  TraceTokenBuffer::Id id_1 =
      store.Append(TracePacketData{slice_1.copy(), state.current_generation()});
  TracePacketData out_1 = store.Extract<TracePacketData>(id_1);
  ASSERT_EQ(out_1.packet, slice_1);
  ASSERT_EQ(out_1.sequence_state, state.current_generation());

  TraceBlobView slice_2 = tbv.slice_off(128ul * 1024, 1024ul);
  TraceTokenBuffer::Id id_2 =
      store.Append(TracePacketData{slice_2.copy(), state.current_generation()});
  TracePacketData out_2 = store.Extract<TracePacketData>(id_2);
  ASSERT_EQ(out_2.packet, slice_2);
  ASSERT_EQ(out_2.sequence_state, state.current_generation());
}

TEST_F(TraceTokenBufferUnittest, TrackEventDataInOut) {
  TraceBlobView tbv(TraceBlob::Allocate(1234));
  TrackEventData ted(tbv.copy(), state.current_generation());
  ted.thread_instruction_count = 123;
  ted.extra_counter_values = {10, 2, 0, 0, 0, 0, 0, 0};
  auto counter_array = ted.extra_counter_values;

  TraceTokenBuffer::Id id = store.Append(std::move(ted));
  TrackEventData extracted = store.Extract<TrackEventData>(id);
  ASSERT_EQ(extracted.trace_packet_data.packet, tbv);
  ASSERT_EQ(extracted.trace_packet_data.sequence_state,
            state.current_generation());
  ASSERT_EQ(extracted.thread_instruction_count, 123);
  ASSERT_EQ(extracted.thread_timestamp, std::nullopt);
  ASSERT_DOUBLE_EQ(extracted.counter_value, 0.0);
  ASSERT_EQ(extracted.extra_counter_values, counter_array);
}

TEST_F(TraceTokenBufferUnittest, ExtractOrAppendAfterFreeMemory) {
  auto unused_res = store.Extract<TraceBlobView>(
      store.Append(TraceBlobView(TraceBlob::Allocate(1234))));
  base::ignore_result(unused_res);

  store.FreeMemory();

  TraceTokenBuffer::Id id =
      store.Append(TraceBlobView(TraceBlob::Allocate(4567)));
  TraceBlobView tbv = store.Extract<TraceBlobView>(id);
  ASSERT_EQ(tbv.size(), 4567u);
}

}  // namespace
}  // namespace trace_processor
}  // namespace perfetto
