// Copyright 2016 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/fsl/socket/socket_drainer.h"

#include <lib/zx/socket.h>
#include <utility>
#include <vector>

#include "src/lib/fxl/logging.h"

namespace fsl {

SocketDrainer::Client::~Client() = default;

SocketDrainer::SocketDrainer(Client* client, async_dispatcher_t* dispatcher)
    : client_(client), dispatcher_(dispatcher), destruction_sentinel_(nullptr) {
  FXL_DCHECK(client_);
}

SocketDrainer::~SocketDrainer() {
  wait_.Cancel();
  if (destruction_sentinel_)
    *destruction_sentinel_ = true;
}

void SocketDrainer::Start(zx::socket source) {
  source_ = std::move(source);
  wait_.set_object(source_.get());
  wait_.set_trigger(ZX_SOCKET_READABLE | ZX_SOCKET_READ_DISABLED |
                    ZX_SOCKET_PEER_CLOSED);
  OnHandleReady(dispatcher_, &wait_, ZX_OK, nullptr);
}

void SocketDrainer::OnHandleReady(async_dispatcher_t* dispatcher,
                                  async::WaitBase* wait, zx_status_t status,
                                  const zx_packet_signal_t* signal) {
  if (status != ZX_OK) {
    client_->OnDataComplete();
    return;
  }

  std::vector<char> buffer(64 * 1024);
  size_t num_bytes = 0;
  status = source_.read(0, buffer.data(), buffer.size(), &num_bytes);
  if (status == ZX_OK) {
    // Calling the user callback, and exiting early if this objects is
    // destroyed.
    bool is_destroyed = false;
    destruction_sentinel_ = &is_destroyed;
    client_->OnDataAvailable(buffer.data(), num_bytes);
    if (is_destroyed)
      return;
    destruction_sentinel_ = nullptr;
    status = ZX_ERR_SHOULD_WAIT;
  }

  if (status == ZX_ERR_SHOULD_WAIT) {
    status = wait->Begin(dispatcher);
    if (status != ZX_OK) {
      client_->OnDataComplete();
    }
    return;
  }

  FXL_DCHECK(status == ZX_ERR_PEER_CLOSED || status == ZX_ERR_BAD_STATE)
      << "Unhandled zx_status_t: " << status;
  client_->OnDataComplete();
}

}  // namespace fsl
