// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "lib/fidl/cpp/internal/proxy_controller.h"

#include <utility>

#include "lib/fidl/cpp/internal/logging.h"

namespace fidl {
namespace internal {
namespace {

constexpr uint32_t kUserspaceTxidMask = 0x7FFFFFFF;

}  // namespace

ProxyController::ProxyController() : reader_(this), next_txid_(1) {}

ProxyController::~ProxyController() = default;

ProxyController::ProxyController(ProxyController&& other)
    : reader_(this), handlers_(std::move(other.handlers_)), next_txid_(other.next_txid_) {
  reader_.TakeChannelAndErrorHandlerFrom(&other.reader());
  other.Reset();
}

ProxyController& ProxyController::operator=(ProxyController&& other) {
  if (this != &other) {
    reader_.TakeChannelAndErrorHandlerFrom(&other.reader());
    handlers_ = std::move(other.handlers_);
    next_txid_ = other.next_txid_;
    other.Reset();
  }
  return *this;
}

zx_status_t ProxyController::Send(const fidl_type_t* type, Message message,
                                  std::unique_ptr<MessageHandler> response_handler) {
  zx_txid_t txid = 0;
  if (response_handler) {
    txid = next_txid_++ & kUserspaceTxidMask;
    while (!txid || handlers_.find(txid) != handlers_.end())
      txid = next_txid_++ & kUserspaceTxidMask;
    message.set_txid(txid);
  }
  const char* error_msg = nullptr;
  zx_status_t status = message.Validate(type, &error_msg);
  if (status != ZX_OK) {
    FIDL_REPORT_ENCODING_ERROR(message, type, error_msg);
    return status;
  }
  status = message.Write(reader_.channel().get(), 0);
  if (status != ZX_OK) {
    FIDL_REPORT_CHANNEL_WRITING_ERROR(message, type, status);
    return status;
  }
  if (response_handler)
    handlers_.emplace(txid, std::move(response_handler));
  return ZX_OK;
}

void ProxyController::Reset() {
  reader_.Reset();
  ClearPendingHandlers();
}

zx_status_t ProxyController::OnMessage(Message message) {
  zx_txid_t txid = message.txid();
  if (!txid) {
    if (!proxy_)
      return ZX_ERR_NOT_SUPPORTED;
    return proxy_->Dispatch_(std::move(message));
  }
  auto it = handlers_.find(txid);
  if (it == handlers_.end())
    return ZX_ERR_NOT_FOUND;
  std::unique_ptr<MessageHandler> handler = std::move(it->second);
  handlers_.erase(it);
  return handler->OnMessage(std::move(message));
}

void ProxyController::OnChannelGone() { ClearPendingHandlers(); }

void ProxyController::ClearPendingHandlers() {
  // Avoid reentrancy problems by first copying the handlers map.
  auto doomed = std::move(handlers_);
  next_txid_ = 1;
  doomed.clear();
}

}  // namespace internal
}  // namespace fidl
