/*
 * Copyright (C) 2017 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.
 */

#ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
#define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_

#include "perfetto/base/proc_utils.h"
#include "perfetto/ext/tracing/core/basic_types.h"
#include "perfetto/ext/tracing/core/shared_memory_abi.h"
#include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
#include "perfetto/ext/tracing/core/trace_writer.h"
#include "perfetto/protozero/message_handle.h"
#include "perfetto/protozero/proto_utils.h"
#include "perfetto/protozero/root_message.h"
#include "perfetto/protozero/scattered_stream_writer.h"
#include "perfetto/tracing/buffer_exhausted_policy.h"
#include "src/tracing/core/patch_list.h"

namespace perfetto {

class SharedMemoryArbiterImpl;

// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
//
// Locking will happen only when a chunk is exhausted and a new one is
// acquired from the arbiter.
//
// TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
// Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
// the TraceWriter will keep writing into unmapped memory.
//
class TraceWriterImpl : public TraceWriter,
                        public protozero::ScatteredStreamWriter::Delegate {
 public:
  // TracePacketHandle is defined in trace_writer.h
  TraceWriterImpl(SharedMemoryArbiterImpl*,
                  WriterID,
                  MaybeUnboundBufferID buffer_id,
                  BufferExhaustedPolicy);
  ~TraceWriterImpl() override;

  // TraceWriter implementation. See documentation in trace_writer.h.
  TracePacketHandle NewTracePacket() override;
  void FinishTracePacket() override;
  // Commits the data pending for the current chunk into the shared memory
  // buffer and sends a CommitDataRequest() to the service.
  // TODO(primiano): right now the |callback| will be called on the IPC thread.
  // This is fine in the current single-thread scenario, but long-term
  // trace_writer_impl.cc should be smarter and post it on the right thread.
  void Flush(std::function<void()> callback = {}) override;
  WriterID writer_id() const override;
  uint64_t written() const override {
    return protobuf_stream_writer_.written();
  }

  void ResetChunkForTesting() { cur_chunk_ = SharedMemoryABI::Chunk(); }
  bool drop_packets_for_testing() const { return drop_packets_; }

 private:
  TraceWriterImpl(const TraceWriterImpl&) = delete;
  TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;

  // ScatteredStreamWriter::Delegate implementation.
  protozero::ContiguousMemoryRange GetNewBuffer() override;
  uint8_t* AnnotatePatch(uint8_t*) override;

  // The per-producer arbiter that coordinates access to the shared memory
  // buffer from several threads.
  SharedMemoryArbiterImpl* const shmem_arbiter_;

  // ID of the current writer.
  const WriterID id_;

  // This is copied into the commit request by SharedMemoryArbiter. See comments
  // in data_source_config.proto for |target_buffer|. If this is a reservation
  // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
  // will also translate the reservation ID to the actual buffer ID.
  const MaybeUnboundBufferID target_buffer_;

  // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
  // exhausted.
  const BufferExhaustedPolicy buffer_exhausted_policy_;

  // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
  // this allows the Service to reconstruct the linear sequence of packets.
  ChunkID next_chunk_id_ = 0;

  // The chunk we are holding onto (if any).
  SharedMemoryABI::Chunk cur_chunk_;

  // Passed to protozero message to write directly into |cur_chunk_|. It
  // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
  // |cur_chunk_| is filled.
  protozero::ScatteredStreamWriter protobuf_stream_writer_;

  // The packet returned via NewTracePacket(). Its owned by this class,
  // TracePacketHandle has just a pointer to it.
  //
  // The caller of NewTracePacket can use TakeStreamWriter() and use the stream
  // writer directly: in that case:
  // * cur_packet_->size() is not up to date. Only the stream writer has the
  //   correct information.
  // * cur_packet_->nested_message() is always nullptr.
  // * cur_packet_->size_field() is still used to track the start of the current
  //   fragment.
  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
      cur_packet_;

  // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
  // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
  uint8_t* cur_fragment_start_ = nullptr;

  // true if we received a call to GetNewBuffer() after NewTracePacket(),
  // false if GetNewBuffer() happened during NewTracePacket() prologue, while
  // starting the TracePacket header.
  bool fragmenting_packet_ = false;

  // Set to |true| when the current chunk contains the maximum number of packets
  // a chunk can contain. When this is |true|, the next packet requires starting
  // a new chunk.
  bool reached_max_packets_per_chunk_ = false;

  // If we fail to acquire a new chunk when the arbiter operates in
  // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
  // mode in which data is written to a local garbage chunk and dropped.
  bool drop_packets_ = false;

  // Whether the trace writer should try to acquire a new chunk from the SMB
  // when the next TracePacket is started because it filled the garbage chunk at
  // least once since the last attempt.
  bool retry_new_chunk_after_packet_ = false;

  // Points to the size field of the last packet we wrote to the current chunk.
  // If the chunk was already returned, this is reset to |nullptr|.
  uint8_t* last_packet_size_field_ = nullptr;

  // When a packet is fragmented across different chunks, the |size_field| of
  // the outstanding nested protobuf messages is redirected onto Patch entries
  // in this list at the time the Chunk is returned (because at that point we
  // have to release the ownership of the current Chunk). This list will be
  // later sent out-of-band to the tracing service, who will patch the required
  // chunks, if they are still around.
  PatchList patch_list_;

  // PID of the process that created the trace writer. Used for a DCHECK that
  // aims to detect unsupported process forks while tracing.
  const base::PlatformProcessId process_id_;

  // True for the first packet on sequence. See the comment for
  // TracePacket.first_packet_on_sequence for more details.
  bool first_packet_on_sequence_ = true;
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
