// 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 "pw_rpc/internal/call_context.h"
#include "pw_rpc/internal/channel.h"
#include "pw_rpc/internal/method.h"
#include "pw_rpc/method_type.h"
#include "pw_rpc/server.h"
#include "pw_rpc/service.h"

namespace pw::rpc::internal {

// Creates a call context for a particular RPC. Unlike the CallContext
// constructor, this function checks the type of RPC at compile time.
template <auto kMethod, MethodType kExpected, typename MethodImpl>
CallContext OpenCall(Server& server,
                     uint32_t channel_id,
                     Service& service,
                     const MethodImpl& method) {
  if constexpr (kExpected == MethodType::kUnary) {
    static_assert(internal::MethodTraits<decltype(kMethod)>::kType == kExpected,
                  "ServerResponse objects may only be opened for unary RPCs.");
  } else if constexpr (kExpected == MethodType::kServerStreaming) {
    static_assert(
        MethodTraits<decltype(kMethod)>::kType == kExpected,
        "ServerWriters may only be opened for server streaming RPCs.");
  } else if constexpr (kExpected == MethodType::kClientStreaming) {
    static_assert(
        MethodTraits<decltype(kMethod)>::kType == kExpected,
        "ServerReaders may only be opened for client streaming RPCs.");
  } else if constexpr (kExpected == MethodType::kBidirectionalStreaming) {
    static_assert(internal::MethodTraits<decltype(kMethod)>::kType == kExpected,
                  "ServerReaderWriters may only be opened for bidirectional "
                  "streaming RPCs.");
  }

  // TODO(hepler): Update the CallContext to store the ID instead, and lookup
  //     the channel by ID.
  rpc::Channel* channel = server.GetChannel(channel_id);
  PW_ASSERT(channel != nullptr);

  return CallContext(server, static_cast<Channel&>(*channel), service, method);
}

}  // namespace pw::rpc::internal
