// 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.
#pragma once

#include <array>
#include <cstddef>
#include <span>

#include "pw_bytes/span.h"
#include "pw_result/result.h"
#include "pw_stream/seek.h"
#include "pw_stream/stream.h"

namespace pw::stream {

class MemoryWriter : public SeekableWriter {
 public:
  using difference_type = ptrdiff_t;
  using reference = const std::byte&;
  using const_reference = const std::byte&;
  using pointer = const std::byte*;
  using const_pointer = const std::byte*;
  using iterator = const std::byte*;
  using const_iterator = const std::byte*;

  constexpr MemoryWriter(ByteSpan dest) : dest_(dest) {}

  // Construct writer with prepopulated data in the buffer. The number of
  // pre-written bytes is provided as `bytes_written`.
  //
  // Precondition: The number of pre-written bytes must not be greater than the
  // size of the provided buffer.
  constexpr MemoryWriter(ByteSpan dest, size_t bytes_written)
      : dest_(dest), position_(bytes_written) {
    PW_ASSERT(position_ <= dest.size_bytes());
  }

  ConstByteSpan WrittenData() const { return dest_.first(position_); }

  void clear() { position_ = 0; }

  std::byte* data() { return dest_.data(); }
  const std::byte* data() const { return dest_.data(); }

  const std::byte& operator[](size_t index) const { return dest_[index]; }

  [[nodiscard]] bool empty() const { return size() == 0u; }

  size_t size() const { return position_; }
  size_t bytes_written() const { return size(); }

  size_t capacity() const { return dest_.size(); }

  const std::byte* begin() const { return dest_.begin(); }
  const std::byte* end() const { return dest_.begin() + position_; }

 private:
  size_t ConservativeLimit(LimitType type) const override {
    return type == LimitType::kWrite ? dest_.size_bytes() - position_ : 0;
  }

  // Implementation for writing data to this stream.
  //
  // If the in-memory buffer is exhausted in the middle of a write, this will
  // perform a partial write and Status::ResourceExhausted() will be returned.
  Status DoWrite(ConstByteSpan data) final;

  Status DoSeek(ssize_t offset, Whence origin) final {
    return CalculateSeek(offset, origin, dest_.size(), position_);
  }

  size_t DoTell() const final { return position_; }

  ByteSpan dest_;
  size_t position_ = 0;
};

template <size_t kSizeBytes>
class MemoryWriterBuffer final : public MemoryWriter {
 public:
  constexpr MemoryWriterBuffer() : MemoryWriter(buffer_) {}

 private:
  std::array<std::byte, kSizeBytes> buffer_;
};

class MemoryReader final : public SeekableReader {
 public:
  constexpr MemoryReader(ConstByteSpan source)
      : source_(source), position_(0) {}

  size_t bytes_read() const { return position_; }

  const std::byte* data() const { return source_.data(); }

 private:
  size_t ConservativeLimit(LimitType type) const override {
    return type == LimitType::kRead ? source_.size_bytes() - position_ : 0;
  }

  Status DoSeek(ssize_t offset, Whence origin) override {
    return CalculateSeek(offset, origin, source_.size(), position_);
  }

  size_t DoTell() const override { return position_; }

  // Implementation for reading data from this stream.
  //
  // If the in-memory buffer does not have enough remaining bytes for what was
  // requested, this will perform a partial read and OK will still be returned.
  StatusWithSize DoRead(ByteSpan dest) override;

  ConstByteSpan source_;
  size_t position_;
};

}  // namespace pw::stream
