// 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_trace_tokenized/trace_buffer.h"

#include <span>

#include "pw_ring_buffer/prefixed_entry_ring_buffer.h"
#include "pw_trace_tokenized/trace_callback.h"

namespace pw {
namespace trace {
namespace {

class TraceBuffer {
 public:
  TraceBuffer() {
    ring_buffer_.SetBuffer(raw_buffer_)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    Callbacks::Instance()
        .RegisterSink(
            TraceSinkStartBlock, TraceSinkAddBytes, TraceSinkEndBlock, this)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  }

  static void TraceSinkStartBlock(void* user_data, size_t size) {
    TraceBuffer* buffer = reinterpret_cast<TraceBuffer*>(user_data);
    if (size > PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES) {
      buffer->block_size_ = 0;  // Skip this block
      return;
    }
    buffer->block_size_ = static_cast<uint16_t>(size);
    buffer->block_idx_ = 0;
  }

  static void TraceSinkAddBytes(void* user_data,
                                const void* bytes,
                                size_t size) {
    TraceBuffer* buffer = reinterpret_cast<TraceBuffer*>(user_data);
    if (buffer->block_size_ == 0 ||
        buffer->block_idx_ + size > buffer->block_size_) {
      return;  // Block is too large, skipping.
    }
    memcpy(&buffer->current_block_[buffer->block_idx_], bytes, size);
    buffer->block_idx_ += size;
  }

  static void TraceSinkEndBlock(void* user_data) {
    TraceBuffer* buffer = reinterpret_cast<TraceBuffer*>(user_data);
    if (buffer->block_idx_ != buffer->block_size_) {
      return;  // Block is too large, skipping.
    }
    buffer->ring_buffer_
        .PushBack(std::span<const std::byte>(&buffer->current_block_[0],
                                             buffer->block_size_))
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  }

  pw::ring_buffer::PrefixedEntryRingBuffer& RingBuffer() {
    return ring_buffer_;
  };

  ConstByteSpan DeringAndViewRawBuffer() {
    ring_buffer_.Dering()
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
    return ByteSpan(raw_buffer_, ring_buffer_.TotalUsedBytes());
  }

 private:
  uint16_t block_size_ = 0;
  uint16_t block_idx_ = 0;
  std::byte current_block_[PW_TRACE_BUFFER_MAX_BLOCK_SIZE_BYTES];
  std::byte raw_buffer_[PW_TRACE_BUFFER_SIZE_BYTES];
  pw::ring_buffer::PrefixedEntryRingBuffer ring_buffer_{false};
};

#if PW_TRACE_BUFFER_SIZE_BYTES > 0
TraceBuffer trace_buffer_instance;
#endif  // PW_TRACE_BUFFER_SIZE_BYTES > 0

}  // namespace

void ClearBuffer() { trace_buffer_instance.RingBuffer().Clear(); }

pw::ring_buffer::PrefixedEntryRingBuffer* GetBuffer() {
  return &trace_buffer_instance.RingBuffer();
}

ConstByteSpan DeringAndViewRawBuffer() {
  return trace_buffer_instance.DeringAndViewRawBuffer();
}

}  // namespace trace
}  // namespace pw
