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

#ifndef LIB_ZX_OBJECT_H_
#define LIB_ZX_OBJECT_H_

#include <lib/zx/object_traits.h>
#include <lib/zx/time.h>
#include <zircon/availability.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

namespace zx {

class port;
class profile;

// Wraps and takes ownership of a handle to an object.
//
// Used for code that wants to operate generically on the zx_handle_t value
// inside a |zx::object| and doesn't otherwise need a template parameter.
//
// The handle is automatically closed when the wrapper is destroyed.
class object_base {
 public:
  void reset(zx_handle_t value = ZX_HANDLE_INVALID) {
    close();
    value_ = value;
  }

  bool is_valid() const { return value_ != ZX_HANDLE_INVALID; }
  explicit operator bool() const { return is_valid(); }

  zx_handle_t get() const { return value_; }

  // Reset the underlying handle, and then get the address of the
  // underlying internal handle storage.
  //
  // Note: The intended purpose is to facilitate interactions with C
  // APIs which expect to be provided a pointer to a handle used as
  // an out parameter.
  zx_handle_t* reset_and_get_address() {
    reset();
    return &value_;
  }

  __attribute__((warn_unused_result)) zx_handle_t release() {
    zx_handle_t result = value_;
    value_ = ZX_HANDLE_INVALID;
    return result;
  }

  zx_status_t get_info(uint32_t topic, void* buffer, size_t buffer_size, size_t* actual_count,
                       size_t* avail_count) const ZX_AVAILABLE_SINCE(7) {
    return zx_object_get_info(get(), topic, buffer, buffer_size, actual_count, avail_count);
  }

  zx_status_t get_property(uint32_t property, void* value, size_t size) const
      ZX_AVAILABLE_SINCE(7) {
    return zx_object_get_property(get(), property, value, size);
  }

  zx_status_t set_property(uint32_t property, const void* value, size_t size) const
      ZX_AVAILABLE_SINCE(7) {
    return zx_object_set_property(get(), property, value, size);
  }

 protected:
  constexpr object_base() : value_(ZX_HANDLE_INVALID) {}

  explicit object_base(zx_handle_t value) : value_(value) {}

  ~object_base() { close(); }

  object_base(const object_base&) = delete;

  void operator=(const object_base&) = delete;

  void close() {
    if (value_ != ZX_HANDLE_INVALID) {
      zx_handle_close(value_);
      value_ = ZX_HANDLE_INVALID;
    }
  }

  zx_handle_t value_;
} ZX_AVAILABLE_SINCE(7);

// Forward declaration for borrow method.
template <typename T>
class unowned;

// Provides type-safe access to operations on a handle.
template <typename T>
class object : public object_base {
 public:
  static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_NONE;

  constexpr object() = default;

  explicit object(zx_handle_t value) : object_base(value) {}

  template <typename U>
  object(object<U>&& other) : object_base(other.release()) {
    static_assert(is_same<T, void>::value, "Receiver must be compatible.");
  }

  template <typename U>
  object<T>& operator=(object<U>&& other) {
    static_assert(is_same<T, void>::value, "Receiver must be compatible.");
    reset(other.release());
    return *this;
  }

  void swap(object<T>& other) {
    zx_handle_t tmp = value_;
    value_ = other.value_;
    other.value_ = tmp;
  }

  zx_status_t duplicate(zx_rights_t rights, object<T>* result) const ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_duplication, "Object must support duplication.");
    zx_handle_t h = ZX_HANDLE_INVALID;
    zx_status_t status = zx_handle_duplicate(value_, rights, &h);
    result->reset(h);
    return status;
  }

  zx_status_t replace(zx_rights_t rights, object<T>* result) ZX_AVAILABLE_SINCE(7) {
    zx_handle_t h = ZX_HANDLE_INVALID;
    zx_status_t status = zx_handle_replace(value_, rights, &h);
    // We store ZX_HANDLE_INVALID to value_ before calling reset on result
    // in case result == this.
    value_ = ZX_HANDLE_INVALID;
    result->reset(h);
    return status;
  }

  zx_status_t wait_one(zx_signals_t signals, zx::time deadline, zx_signals_t* pending) const
      ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_wait, "Object is not waitable.");
    return zx_object_wait_one(value_, signals, deadline.get(), pending);
  }

  zx_status_t wait_async(const object<port>& port, uint64_t key, zx_signals_t signals,
                         uint32_t options) const ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_wait, "Object is not waitable.");
    return zx_object_wait_async(value_, port.get(), key, signals, options);
  }

  static zx_status_t wait_many(zx_wait_item_t* wait_items, uint32_t count, zx::time deadline)
      ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_wait, "Object is not waitable.");
    return zx_object_wait_many(wait_items, count, deadline.get());
  }

  zx_status_t signal(uint32_t clear_mask, uint32_t set_mask) const ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_user_signal, "Object must support user signals.");
    return zx_object_signal(get(), clear_mask, set_mask);
  }

  zx_status_t signal_peer(uint32_t clear_mask, uint32_t set_mask) const ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_user_signal, "Object must support user signals.");
    static_assert(object_traits<T>::has_peer_handle, "Object must have peer object.");
    return zx_object_signal_peer(get(), clear_mask, set_mask);
  }

  zx_status_t get_child(uint64_t koid, zx_rights_t rights, object<void>* result) const
      ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_get_child, "Object must support getting children.");
    // Allow for |result| and |this| being the same container, though that
    // can only happen for |T=void|, due to strict aliasing.
    object<void> h;
    zx_status_t status = zx_object_get_child(value_, koid, rights, h.reset_and_get_address());
    result->reset(h.release());
    return status;
  }

  zx_status_t set_profile(const object<profile>& profile, uint32_t options) const
      ZX_AVAILABLE_SINCE(7) {
    static_assert(object_traits<T>::supports_set_profile,
                  "Object must support scheduling profiles.");
    return zx_object_set_profile(get(), profile.get(), options);
  }

  // Returns a type-safe wrapper of the underlying handle that does not claim ownership.
  unowned<T> borrow() const { return unowned<T>(get()); }

 private:
  template <typename A, typename B>
  struct is_same {
    static const bool value = false;
  };

  template <typename A>
  struct is_same<A, A> {
    static const bool value = true;
  };
} ZX_AVAILABLE_SINCE(7);

template <typename T>
bool operator==(const object<T>& a, const object<T>& b) {
  return a.get() == b.get();
}

template <typename T>
bool operator!=(const object<T>& a, const object<T>& b) {
  return !(a == b);
}

template <typename T>
bool operator<(const object<T>& a, const object<T>& b) {
  return a.get() < b.get();
}

template <typename T>
bool operator>(const object<T>& a, const object<T>& b) {
  return a.get() > b.get();
}

template <typename T>
bool operator<=(const object<T>& a, const object<T>& b) {
  return !(a.get() > b.get());
}

template <typename T>
bool operator>=(const object<T>& a, const object<T>& b) {
  return !(a.get() < b.get());
}

template <typename T>
bool operator==(zx_handle_t a, const object<T>& b) {
  return a == b.get();
}

template <typename T>
bool operator!=(zx_handle_t a, const object<T>& b) {
  return !(a == b);
}

template <typename T>
bool operator<(zx_handle_t a, const object<T>& b) {
  return a < b.get();
}

template <typename T>
bool operator>(zx_handle_t a, const object<T>& b) {
  return a > b.get();
}

template <typename T>
bool operator<=(zx_handle_t a, const object<T>& b) {
  return !(a > b.get());
}

template <typename T>
bool operator>=(zx_handle_t a, const object<T>& b) {
  return !(a < b.get());
}

template <typename T>
bool operator==(const object<T>& a, zx_handle_t b) {
  return a.get() == b;
}

template <typename T>
bool operator!=(const object<T>& a, zx_handle_t b) {
  return !(a == b);
}

template <typename T>
bool operator<(const object<T>& a, zx_handle_t b) {
  return a.get() < b;
}

template <typename T>
bool operator>(const object<T>& a, zx_handle_t b) {
  return a.get() > b;
}

template <typename T>
bool operator<=(const object<T>& a, zx_handle_t b) {
  return !(a.get() > b);
}

template <typename T>
bool operator>=(const object<T>& a, zx_handle_t b) {
  return !(a.get() < b);
}

// Wraps a handle to an object to provide type-safe access to its operations
// but does not take ownership of it.  The handle is not closed when the
// wrapper is destroyed.
//
// All use of unowned<object<T>> as an object<T> is via a dereference operator,
// as illustrated below:
//
// void do_something(const zx::event& event);
//
// void example(zx_handle_t event_handle) {
//     do_something(*zx::unowned<event>(event_handle));
// }
//
// Convenience aliases are provided for all object types, for example:
//
// zx::unowned_event(handle)->signal(..)
template <typename T>
class unowned final {
 public:
  explicit unowned(zx_handle_t h) : value_(h) {}
  explicit unowned(const T& owner) : unowned(owner.get()) {}
  explicit unowned(const unowned& other) : unowned(*other) {}
  constexpr unowned() = default;
  unowned(unowned&& other) = default;

  ~unowned() { release_value(); }

  unowned& operator=(const unowned& other) {
    if (&other == this) {
      return *this;
    }

    *this = unowned(other);
    return *this;
  }
  unowned& operator=(unowned&& other) {
    release_value();
    value_ = static_cast<T&&>(other.value_);
    return *this;
  }

  const T& operator*() const { return value_; }
  const T* operator->() const { return &value_; }

 private:
  void release_value() {
    zx_handle_t h = value_.release();
    static_cast<void>(h);
  }

  T value_;
} ZX_AVAILABLE_SINCE(7);

template <typename T>
bool operator==(const unowned<T>& a, const unowned<T>& b) {
  return a->get() == b->get();
}

template <typename T>
bool operator!=(const unowned<T>& a, const unowned<T>& b) {
  return !(a == b);
}

template <typename T>
bool operator<(const unowned<T>& a, const unowned<T>& b) {
  return a->get() < b->get();
}

template <typename T>
bool operator>(const unowned<T>& a, const unowned<T>& b) {
  return a->get() > b->get();
}

template <typename T>
bool operator<=(const unowned<T>& a, const unowned<T>& b) {
  return !(a > b);
}

template <typename T>
bool operator>=(const unowned<T>& a, const unowned<T>& b) {
  return !(a < b);
}

template <typename T>
bool operator==(zx_handle_t a, const unowned<T>& b) {
  return a == b->get();
}

template <typename T>
bool operator!=(zx_handle_t a, const unowned<T>& b) {
  return !(a == b);
}

template <typename T>
bool operator<(zx_handle_t a, const unowned<T>& b) {
  return a < b->get();
}

template <typename T>
bool operator>(zx_handle_t a, const unowned<T>& b) {
  return a > b->get();
}

template <typename T>
bool operator<=(zx_handle_t a, const unowned<T>& b) {
  return !(a > b);
}

template <typename T>
bool operator>=(zx_handle_t a, const unowned<T>& b) {
  return !(a < b);
}

template <typename T>
bool operator==(const unowned<T>& a, zx_handle_t b) {
  return a->get() == b;
}

template <typename T>
bool operator!=(const unowned<T>& a, zx_handle_t b) {
  return !(a == b);
}

template <typename T>
bool operator<(const unowned<T>& a, zx_handle_t b) {
  return a->get() < b;
}

template <typename T>
bool operator>(const unowned<T>& a, zx_handle_t b) {
  return a->get() > b;
}

template <typename T>
bool operator<=(const unowned<T>& a, zx_handle_t b) {
  return !(a > b);
}

template <typename T>
bool operator>=(const unowned<T>& a, zx_handle_t b) {
  return !(a < b);
}

}  // namespace zx

#endif  // LIB_ZX_OBJECT_H_
