// 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 ServiceImpl,
          typename MethodImpl>
CallContext OpenContext(Server& server,
                        uint32_t channel_id,
                        ServiceImpl& service,
                        const MethodImpl& method) {
  using Info = internal::MethodInfo<kMethod>;
  if constexpr (kExpected == MethodType::kUnary) {
    static_assert(Info::kType == kExpected,
                  "ServerResponse objects may only be opened for unary RPCs.");
  } else if constexpr (kExpected == MethodType::kServerStreaming) {
    static_assert(
        Info::kType == kExpected,
        "ServerWriters may only be opened for server streaming RPCs.");
  } else if constexpr (kExpected == MethodType::kClientStreaming) {
    static_assert(
        Info::kType == kExpected,
        "ServerReaders may only be opened for client streaming RPCs.");
  } else if constexpr (kExpected == MethodType::kBidirectionalStreaming) {
    static_assert(Info::kType == kExpected,
                  "ServerReaderWriters may only be opened for bidirectional "
                  "streaming RPCs.");
  }

  // TODO(pwbug/505): 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);

  // Unrequested RPCs always use 0 as the call ID. When an actual request is
  // sent, the call will be replaced with its real ID.
  constexpr uint32_t kOpenCallId = 0;

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

}  // namespace pw::rpc::internal
