// Copyright 2021 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_protobuf/encoder.h"

#include <limits>

namespace pw::protobuf {

Status Encoder::WriteUint64(uint32_t field_number, uint64_t value) {
  std::byte* original_cursor = cursor_;
  WriteFieldKey(field_number, WireType::kVarint);
  WriteVarint(value);
  return IncreaseParentSize(cursor_ - original_cursor);
}

// Encodes a base-128 varint to the buffer.
Status Encoder::WriteVarint(uint64_t value) {
  if (!encode_status_.ok()) {
    return encode_status_;
  }

  std::span varint_buf = buffer_.last(RemainingSize());
  if (varint_buf.empty()) {
    encode_status_ = Status::ResourceExhausted();
    return encode_status_;
  }

  size_t written = pw::varint::EncodeLittleEndianBase128(value, varint_buf);
  if (written == 0) {
    encode_status_ = Status::ResourceExhausted();
    return encode_status_;
  }

  cursor_ += written;
  return OkStatus();
}

Status Encoder::WriteRawBytes(const std::byte* ptr, size_t size) {
  if (!encode_status_.ok()) {
    return encode_status_;
  }

  if (size > RemainingSize()) {
    encode_status_ = Status::ResourceExhausted();
    return encode_status_;
  }

  // Memmove the value into place as it's possible that it shares the encode
  // buffer on a memory-constrained system.
  std::memmove(cursor_, ptr, size);

  cursor_ += size;
  return OkStatus();
}

Status Encoder::Push(uint32_t field_number) {
  if (!encode_status_.ok()) {
    return encode_status_;
  }

  if (blob_count_ == blob_locations_.size() || depth_ == blob_stack_.size()) {
    encode_status_ = Status::ResourceExhausted();
    return encode_status_;
  }

  // Write the key for the nested field.
  std::byte* original_cursor = cursor_;
  if (Status status = WriteFieldKey(field_number, WireType::kDelimited);
      !status.ok()) {
    encode_status_ = status;
    return status;
  }

  if (sizeof(SizeType) > RemainingSize()) {
    // Rollback if there isn't enough space.
    cursor_ = original_cursor;
    encode_status_ = Status::ResourceExhausted();
    return encode_status_;
  }

  // Update parent size with the written key.
  PW_TRY(IncreaseParentSize(cursor_ - original_cursor));

  union {
    std::byte* cursor;
    SizeType* size_cursor;
  };

  // Create a size entry for the new blob and append it to both the nesting
  // stack and location list.
  cursor = cursor_;
  *size_cursor = 0;
  blob_locations_[blob_count_++] = size_cursor;
  blob_stack_[depth_++] = size_cursor;

  cursor_ += sizeof(*size_cursor);
  return OkStatus();
}

Status Encoder::Pop() {
  if (!encode_status_.ok()) {
    return encode_status_;
  }

  if (depth_ == 0) {
    encode_status_ = Status::FailedPrecondition();
    return encode_status_;
  }

  // Update the parent's size with how much total space the child will take
  // after its size field is varint encoded.
  SizeType child_size = *blob_stack_[--depth_];
  PW_TRY(IncreaseParentSize(child_size + VarintSizeBytes(child_size)));

  // Encode the child
  if (Status status = EncodeFrom(blob_count_ - 1).status(); !status.ok()) {
    encode_status_ = status;
    return encode_status_;
  }
  blob_count_--;

  return OkStatus();
}

Result<ConstByteSpan> Encoder::Encode() { return EncodeFrom(0); }

Result<ConstByteSpan> Encoder::EncodeFrom(size_t blob) {
  if (!encode_status_.ok()) {
    return encode_status_;
  }

  if (blob >= blob_count_) {
    // If there are no nested blobs, the buffer already contains a valid proto.
    return Result<ConstByteSpan>(buffer_.first(EncodedSize()));
  }

  union {
    std::byte* read_cursor;
    SizeType* size_cursor;
  };

  // Starting from the first blob, encode each size field as a varint and
  // shift all subsequent data downwards.
  size_cursor = blob_locations_[blob];
  std::byte* write_cursor = read_cursor;

  while (read_cursor < cursor_) {
    SizeType nested_size = *size_cursor;

    std::span<std::byte> varint_buf(write_cursor, sizeof(*size_cursor));
    size_t varint_size =
        pw::varint::EncodeLittleEndianBase128(nested_size, varint_buf);

    // Place the write cursor after the encoded varint and the read cursor at
    // the location of the next proto field.
    write_cursor += varint_size;
    read_cursor += varint_buf.size();

    size_t to_copy;

    if (blob == blob_count_ - 1) {
      to_copy = cursor_ - read_cursor;
    } else {
      std::byte* end = reinterpret_cast<std::byte*>(blob_locations_[blob + 1]);
      to_copy = end - read_cursor;
    }

    std::memmove(write_cursor, read_cursor, to_copy);
    write_cursor += to_copy;
    read_cursor += to_copy;

    ++blob;
  }

  // Point the cursor to the end of the encoded proto.
  cursor_ = write_cursor;
  return Result<ConstByteSpan>(buffer_.first(EncodedSize()));
}

Status Encoder::IncreaseParentSize(size_t size_bytes) {
  if (!encode_status_.ok()) {
    return encode_status_;
  }

  if (depth_ == 0) {
    return OkStatus();
  }

  size_t current_size = *blob_stack_[depth_ - 1];

  constexpr size_t max_size =
      std::min(varint::MaxValueInBytes(sizeof(SizeType)),
               static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()));

  if (size_bytes > max_size || current_size > max_size - size_bytes) {
    encode_status_ = Status::OutOfRange();
    return encode_status_;
  }

  *blob_stack_[depth_ - 1] = current_size + size_bytes;
  return OkStatus();
}

}  // namespace pw::protobuf
