// 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 "pw_bytes/span.h"
#include "pw_rpc/internal/base_server_writer.h"
#include "pw_rpc/internal/method.h"
#include "pw_rpc/internal/method_type.h"
#include "pw_status/status_with_size.h"

namespace pw::rpc {

class RawServerWriter : public internal::BaseServerWriter {
 public:
  RawServerWriter() = default;

  // Returns a buffer in which a response payload can be built.
  ByteSpan PayloadBuffer() { return AcquirePayloadBuffer(); }

  // Sends a response packet with the given raw payload. The payload can either
  // be in the buffer previously acquired from PayloadBuffer(), or an arbitrary
  // external buffer.
  Status Write(ConstByteSpan response);
};

namespace internal {

// A RawMethod is a method invoker which does not perform any automatic protobuf
// serialization or deserialization. The implementer is given the raw binary
// payload of incoming requests, and is responsible for encoding responses to a
// provided buffer. This is intended for use in methods which would have large
// protobuf data structure overhead to lower stack usage, or in methods packing
// responses up to a channel's MTU.
class RawMethod : public Method {
 public:
  template <auto method>
  constexpr static RawMethod Unary(uint32_t id) {
    return RawMethod(
        id,
        UnaryInvoker,
        {.unary = [](ServerCall& call, ConstByteSpan req, ByteSpan res) {
          return method(call, req, res);
        }});
  }

  template <auto method>
  constexpr static RawMethod ServerStreaming(uint32_t id) {
    return RawMethod(id,
                     ServerStreamingInvoker,
                     Function{.server_streaming = [](ServerCall& call,
                                                     ConstByteSpan req,
                                                     BaseServerWriter& writer) {
                       method(call, req, static_cast<RawServerWriter&>(writer));
                     }});
  }

 private:
  using UnaryFunction = StatusWithSize (*)(ServerCall&,
                                           ConstByteSpan,
                                           ByteSpan);

  using ServerStreamingFunction = void (*)(ServerCall&,
                                           ConstByteSpan,
                                           BaseServerWriter&);
  union Function {
    UnaryFunction unary;
    ServerStreamingFunction server_streaming;
    // TODO(frolv): Support client and bidirectional streaming.
  };

  constexpr RawMethod(uint32_t id, Invoker invoker, Function function)
      : Method(id, invoker), function_(function) {}

  static void UnaryInvoker(const Method& method,
                           ServerCall& call,
                           const Packet& request) {
    static_cast<const RawMethod&>(method).CallUnary(call, request);
  }

  static void ServerStreamingInvoker(const Method& method,
                                     ServerCall& call,
                                     const Packet& request) {
    static_cast<const RawMethod&>(method).CallServerStreaming(call, request);
  }

  void CallUnary(ServerCall& call, const Packet& request) const;
  void CallServerStreaming(ServerCall& call, const Packet& request) const;

  // Stores the user-defined RPC in a generic wrapper.
  Function function_;
};

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