// Copyright 2019 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/fdio/fdio.h>
#include <lib/zxio/null.h>

#include <atomic>
#include <cstdarg>
#include <cstdint>

#include "internal.h"

struct fdio {
  // The operation function table which encapsulates specialized I/O
  // transport under a common interface.
  const fdio_ops_t* ops;

  // The number of references on this object. Note that each appearance
  // in the fd table counts as one reference on the corresponding object.
  // Ongoing operations will also contribute to the refcount.
  std::atomic_int_fast32_t refcount;

  // The number of times this fdio object appears in the fd table.
  int32_t dupcount;

  // |ioflag| contains mutable properties of this object, shared by
  // different transports. Possible values are |IOFLAG_*| in private.h.
  uint32_t ioflag;

  // The zxio object, if the zxio transport is selected in |ops|.
  zxio_storage_t storage;

  // Used to implement SO_RCVTIMEO. See `man 7 socket` for details.
  zx::duration rcvtimeo;

  // Used to implement SO_SNDTIMEO. See `man 7 socket` for details.
  zx::duration sndtimeo;
};

// fdio_reserved_io is a globally shared fdio_t that is used to represent a
// reservation in the fdtab. If a user observes fdio_reserved_io there is a race
// condition in their code or they are looking up fd's by number.
// fdio_reserved_io is used in the time between a user requesting an operation
// that creates and fd, and the time when a remote operation to create the
// backing fdio_t is created, without holding the fdtab lock. Examples include
// open() of a file, or accept() on a socket.
static fdio_t fdio_reserved_io = {
    // TODO(raggi): It may be ideal to replace these operations with ones that
    // more directly encode the result that a user must have implemented a race
    // in order to invoke them.
    .ops = nullptr,
    .refcount = 1,
    .dupcount = 1,
    .ioflag = 0,
    .storage = {},
    .rcvtimeo = zx::duration::infinite(),
    .sndtimeo = zx::duration::infinite(),
};

fdio_t* fdio_get_reserved_io() { return &fdio_reserved_io; }

__EXPORT
zxio_t* fdio_get_zxio(fdio_t* io) { return &io->storage.io; }

const fdio_ops_t* fdio_get_ops(const fdio_t* io) { return io->ops; }

int32_t fdio_get_dupcount(const fdio_t* io) { return io->dupcount; }

void fdio_dupcount_acquire(fdio_t* io) { io->dupcount++; }

void fdio_dupcount_release(fdio_t* io) { io->dupcount--; }

uint32_t* fdio_get_ioflag(fdio_t* io) { return &io->ioflag; }

zxio_storage_t* fdio_get_zxio_storage(fdio_t* io) { return &io->storage; }

fdio_t* fdio_alloc(const fdio_ops_t* ops) {
  return new fdio_t{
      .ops = ops,
      .refcount = 1,
      .dupcount = 0,
      .ioflag = 0,
      .storage = {},
      .rcvtimeo = zx::duration::infinite(),
      .sndtimeo = zx::duration::infinite(),
  };
}

zx::duration* fdio_get_rcvtimeo(fdio_t* io) { return &io->rcvtimeo; }
zx::duration* fdio_get_sndtimeo(fdio_t* io) { return &io->sndtimeo; }

void fdio_acquire(fdio_t* io) { io->refcount.fetch_add(1); }

zx_status_t fdio_release(fdio_t* io) {
  if (io->refcount.fetch_sub(1) == 1) {
    zx_status_t status = fdio_get_ops(io)->close(io);
    delete io;
    return status;
  }
  return ZX_OK;
}

bool fdio_is_last_reference(fdio_t* io) { return io->refcount.load() == 1; }
