// 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.

#include "pw_rpc/client.h"

#include <mutex>

#include "pw_log/log.h"
#include "pw_rpc/internal/client_call.h"
#include "pw_rpc/internal/packet.h"
#include "pw_status/try.h"

namespace pw::rpc {
namespace {

using internal::Packet;
using internal::PacketType;

}  // namespace

Status Client::ProcessPacket(ConstByteSpan data) {
  PW_TRY_ASSIGN(Result<Packet> result,
                Endpoint::ProcessPacket(data, Packet::kClient));
  Packet& packet = *result;

  // Find an existing call for this RPC, if any.
  internal::rpc_lock().lock();
  internal::ClientCall* call =
      static_cast<internal::ClientCall*>(FindCall(packet));

  internal::Channel* channel = GetInternalChannel(packet.channel_id());

  if (channel == nullptr) {
    PW_LOG_WARN("RPC client received a packet for an unregistered channel");
    internal::rpc_lock().unlock();
    return Status::Unavailable();
  }

  if (call == nullptr || call->id() != packet.call_id()) {
    internal::rpc_lock().unlock();
    // The call for the packet does not exist. If the packet is a server stream
    // message, notify the server so that it can kill the stream. Otherwise,
    // silently drop the packet (as it would terminate the RPC anyway).
    if (packet.type() == PacketType::SERVER_STREAM) {
      PW_LOG_WARN("RPC client received stream message for an unknown call");
      channel->Send(Packet::ClientError(packet, Status::FailedPrecondition()))
          .IgnoreError();
    }
    return OkStatus();  // OK since the packet was handled
  }

  switch (packet.type()) {
    case PacketType::RESPONSE:
      // RPCs without a server stream include a payload with the final packet.
      if (call->has_server_stream()) {
        static_cast<internal::StreamResponseClientCall&>(*call).HandleCompleted(
            packet.status());
      } else {
        static_cast<internal::UnaryResponseClientCall&>(*call).HandleCompleted(
            packet.payload(), packet.status());
      }
      break;
    case PacketType::SERVER_ERROR:
      call->HandleError(packet.status());
      break;
    case PacketType::SERVER_STREAM:
      if (call->has_server_stream()) {
        call->HandlePayload(packet.payload());
      } else {
        PW_LOG_DEBUG("Received SERVER_STREAM for RPC without a server stream");
        call->HandleError(Status::InvalidArgument());
        // Report the error to the server so it can abort the RPC.
        channel->Send(Packet::ClientError(packet, Status::InvalidArgument()))
            .IgnoreError();  // Errors are logged in Channel::Send.
      }
      break;
    default:
      internal::rpc_lock().unlock();
      PW_LOG_WARN("pw_rpc client unable to handle packet of type %u",
                  static_cast<unsigned>(packet.type()));
  }

  return OkStatus();  // OK since the packet was handled
}

}  // namespace pw::rpc
