// Copyright (c) 2023 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_COMMON_TEST_TOOLS_MOCK_STREAMS_H_
#define QUICHE_COMMON_TEST_TOOLS_MOCK_STREAMS_H_

#include <algorithm>
#include <cstddef>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "quiche/common/platform/api/quiche_test.h"
#include "quiche/common/quiche_mem_slice.h"
#include "quiche/common/quiche_stream.h"

namespace quiche::test {

// Mockable stream that stores all of the data into an std::string by default.
class MockWriteStream : public quiche::WriteStream {
 public:
  MockWriteStream() {
    ON_CALL(*this, CanWrite()).WillByDefault(testing::Return(true));
    ON_CALL(*this, Writev(testing::_, testing::_))
        .WillByDefault([&](absl::Span<quiche::QuicheMemSlice> data,
                           const StreamWriteOptions& options) {
          return AppendToData(data, options);
        });
  }

  MOCK_METHOD(absl::Status, Writev,
              (absl::Span<quiche::QuicheMemSlice> data,
               const StreamWriteOptions& options),
              (override));
  MOCK_METHOD(bool, CanWrite, (), (const, override));

  absl::Status AppendToData(absl::Span<quiche::QuicheMemSlice> data,
                            const StreamWriteOptions& options) {
    for (const quiche::QuicheMemSlice& fragment : data) {
      data_.append(fragment.data(), fragment.length());
    }
    ProcessOptions(options);
    return absl::OkStatus();
  }
  void ProcessOptions(const StreamWriteOptions& options) {
    fin_written_ |= options.send_fin();
  }

  std::string& data() { return data_; }
  bool fin_written() { return fin_written_; }

 private:
  std::string data_;
  bool fin_written_ = false;
};

// Reads stream data from an std::string buffer.
class ReadStreamFromString : public ReadStream {
 public:
  explicit ReadStreamFromString(std::string* data) : data_(data) {}

  ReadResult Read(absl::Span<char> buffer) override {
    size_t data_to_copy = std::min(buffer.size(), data_->size());
    std::copy(data_->begin(), data_->begin() + data_to_copy, buffer.begin());
    *data_ = data_->substr(data_to_copy);
    return ReadResult{data_to_copy, data_->empty() && fin_};
  }
  ReadResult Read(std::string* output) override {
    size_t bytes = data_->size();
    output->append(std::move(*data_));
    data_->clear();
    return ReadResult{bytes, fin_};
  }

  size_t ReadableBytes() const override { return data_->size(); }

  virtual PeekResult PeekNextReadableRegion() const override {
    PeekResult result;
    result.peeked_data = *data_;
    result.fin_next = data_->empty() && fin_;
    result.all_data_received = fin_;
    return result;
  }

  bool SkipBytes(size_t bytes) override {
    *data_ = data_->substr(bytes);
    return data_->empty() && fin_;
  }

  void set_fin() { fin_ = true; }

 private:
  std::string* data_;
  bool fin_ = false;
};

}  // namespace quiche::test

#endif  // QUICHE_COMMON_TEST_TOOLS_MOCK_STREAMS_H_
