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

#include <cstring>

#include "pw_bytes/span.h"
#include "pw_rpc/internal/call_context.h"
#include "pw_rpc/method_type.h"

namespace pw::rpc::internal::test {

// Fake server reader/writer classes for testing use. These also serve as a
// model for how the RPC implementations (raw, pwpb, Nanopb) structure their
// reader/writer classes.
//
// Readers/writers use an unusual inheritance hierarchy. Rather than having the
// ServerReaderWriter inherit from both the Reader and Writer classes, the
// readers and writers inherit from it, but hide the unsupported functionality.
// A ReaderWriter defines conversions to Reader and Writer, so it acts as if it
// inherited from both. This approach is unusual but necessary to have all
// classes use a single IntrusiveList::Item base and to avoid virtual methods or
// virtual inheritance.
//
// Call's public API is intended for rpc::Server, so hide the public methods
// with private inheritance.
class FakeServerReaderWriter : private internal::ServerCall {
 public:
  constexpr FakeServerReaderWriter() = default;

  // On a real reader/writer, this constructor would not be exposed.
  FakeServerReaderWriter(const CallContext& context,
                         MethodType type = MethodType::kBidirectionalStreaming)
      : ServerCall(context, type) {}

  FakeServerReaderWriter(FakeServerReaderWriter&&) = default;
  FakeServerReaderWriter& operator=(FakeServerReaderWriter&&) = default;

  // Pull in protected functions from the hidden Call base as needed.
  using Call::active;
  using Call::set_on_error;
  using Call::set_on_next;
  using ServerCall::set_on_client_stream_end;

  Status Finish(Status status = OkStatus()) {
    return CloseAndSendResponse(status);
  }

  using Call::PayloadBuffer;
  using Call::Write;

  // Expose a few additional methods for test use.
  ServerCall& as_server_call() { return *this; }
};

class FakeServerWriter : private FakeServerReaderWriter {
 public:
  constexpr FakeServerWriter() = default;

  FakeServerWriter(const CallContext& context)
      : FakeServerReaderWriter(context, MethodType::kServerStreaming) {}
  FakeServerWriter(FakeServerWriter&&) = default;

  // Common reader/writer functions.
  using FakeServerReaderWriter::active;
  using FakeServerReaderWriter::Finish;
  using FakeServerReaderWriter::set_on_error;
  using FakeServerReaderWriter::Write;

  // Functions for test use.
  using FakeServerReaderWriter::as_server_call;
  using FakeServerReaderWriter::PayloadBuffer;
};

class FakeServerReader : private FakeServerReaderWriter {
 public:
  constexpr FakeServerReader() = default;

  FakeServerReader(const CallContext& context)
      : FakeServerReaderWriter(context, MethodType::kClientStreaming) {}

  FakeServerReader(FakeServerReader&&) = default;

  using FakeServerReaderWriter::active;
  using FakeServerReaderWriter::as_server_call;

  // Functions for test use.
  using FakeServerReaderWriter::PayloadBuffer;
};

}  // namespace pw::rpc::internal::test
