// 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 <type_traits>
#include <utility>

#include "pw_rpc/internal/method.h"
#include "pw_rpc/method_type.h"

namespace pw::rpc::internal {

// Base class for different combinations of possible service methods. Derived
// classes should contain a union of different method types, one of which is a
// base Method.
class MethodUnion {
 public:
  constexpr const Method& method() const;
};

class CoreMethodUnion : public MethodUnion {
 public:
  constexpr const Method& method() const { return impl_.method; }

 private:
  // All derived MethodUnions must contain a union of different method
  // implementations as their only member.
  union {
    Method method;
  } impl_;
};

constexpr const Method& MethodUnion::method() const {
  // This is an ugly hack. As all MethodUnion classes contain a union of Method
  // derivatives, CoreMethodUnion is used to extract a generic Method from the
  // specific implementation.
  return static_cast<const CoreMethodUnion*>(this)->method();
}

// Templated false value for use in static_assert(false) statements.
template <typename...>
constexpr std::false_type kCheckMethodSignature{};

// In static_assert messages, use newlines in GCC since it displays them
// correctly. Clang displays \n, which is not helpful.
#ifdef __clang__
#define _PW_RPC_FORMAT_ERROR_MESSAGE(msg, signature) msg " " signature
#else
#define _PW_RPC_FORMAT_ERROR_MESSAGE(msg, signature) \
  "\n" msg "\n\n    " signature "\n"
#endif  // __clang__

#define _PW_RPC_FUNCTION_ERROR(type, return_type, args)                   \
  _PW_RPC_FORMAT_ERROR_MESSAGE(                                           \
      "This RPC is a " type                                               \
      " RPC, but its function signature is not correct. The function "    \
      "signature is determined by the protobuf library in use, but " type \
      " RPC implementations generally take the form:",                    \
      return_type " MethodName(ServerContext&, " args ")")

// This function is called if an RPC method implementation's signature is not
// correct. It triggers a static_assert with an error message tailored to the
// expected RPC type.
template <auto kMethod,
          MethodType kExpected,
          typename InvalidImpl = MethodImplementation<kMethod>>
constexpr auto InvalidMethod(uint32_t) {
  if constexpr (kExpected == MethodType::kUnary) {
    static_assert(
        kCheckMethodSignature<decltype(kMethod)>,
        _PW_RPC_FUNCTION_ERROR("unary", "Status", "Request, Response"));
  } else if constexpr (kExpected == MethodType::kServerStreaming) {
    static_assert(
        kCheckMethodSignature<decltype(kMethod)>,
        _PW_RPC_FUNCTION_ERROR(
            "server streaming", "void", "Request, ServerWriter<Response>&"));
  } else if constexpr (kExpected == MethodType::kClientStreaming) {
    static_assert(
        kCheckMethodSignature<decltype(kMethod)>,
        _PW_RPC_FUNCTION_ERROR(
            "client streaming", "void", "ServerReader<Request, Request>&"));
  } else if constexpr (kExpected == MethodType::kBidirectionalStreaming) {
    static_assert(
        kCheckMethodSignature<decltype(kMethod)>,
        _PW_RPC_FUNCTION_ERROR("bidirectional streaming",
                               "void",
                               "ServerReaderWriter<Request, Response>&"));
  } else {
    static_assert(kCheckMethodSignature<decltype(kMethod)>,
                  "Unsupported MethodType");
  }
  return InvalidImpl::Invalid();
}

#undef _PW_RPC_FORMAT_ERROR_MESSAGE
#undef _PW_RPC_FUNCTION_ERROR

// This function checks the type of the method and calls the appropriate
// function to create the method instance.
template <auto kMethod, typename MethodImpl, MethodType kType, typename... Args>
constexpr auto GetMethodFor(uint32_t id, Args&&... args) {
  if constexpr (MethodTraits<decltype(kMethod)>::kType != kType) {
    return InvalidMethod<kMethod, kType>(id);
  } else if constexpr (kType == MethodType::kUnary) {
    if constexpr (MethodTraits<decltype(kMethod)>::kSynchronous) {
      return MethodImpl::template SynchronousUnary<kMethod>(
          id, std::forward<Args>(args)...);
    } else {
      return MethodImpl::template AsynchronousUnary<kMethod>(
          id, std::forward<Args>(args)...);
    }
  } else if constexpr (kType == MethodType::kServerStreaming) {
    return MethodImpl::template ServerStreaming<kMethod>(
        id, std::forward<Args>(args)...);
  } else if constexpr (kType == MethodType::kClientStreaming) {
    return MethodImpl::template ClientStreaming<kMethod>(
        id, std::forward<Args>(args)...);
  } else if constexpr (kType == MethodType::kBidirectionalStreaming) {
    return MethodImpl::template BidirectionalStreaming<kMethod>(
        id, std::forward<Args>(args)...);
  } else {
    static_assert(kCheckMethodSignature<MethodImpl>, "Invalid MethodType");
  }
}

}  // namespace pw::rpc::internal
