// Copyright (c) 2009 The Chromium Embedded Framework 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 CEF_LIBCEF_DLL_CTOCPP_CTOCPP_REF_COUNTED_H_
#define CEF_LIBCEF_DLL_CTOCPP_CTOCPP_REF_COUNTED_H_
#pragma once

#include "include/base/cef_logging.h"
#include "include/base/cef_macros.h"
#include "include/capi/cef_base_capi.h"
#include "include/cef_base.h"
#include "libcef_dll/wrapper_types.h"

// Wrap a C structure with a C++ class. This is used when the implementation
// exists on the other side of the DLL boundary but will have methods called on
// this side of the DLL boundary.
template <class ClassName, class BaseName, class StructName>
class CefCToCppRefCounted : public BaseName {
 public:
  // Create a new wrapper instance for a structure reference received from the
  // other side.
  static CefRefPtr<BaseName> Wrap(StructName* s);

  // Retrieve the underlying structure reference from a wrapper instance for
  // return back to the other side.
  static StructName* Unwrap(CefRefPtr<BaseName> c);

  // CefBaseRefCounted methods increment/decrement reference counts on both this
  // object and the underlying wrapped structure.
  void AddRef() const {
    UnderlyingAddRef();
    ref_count_.AddRef();
  }
  bool Release() const;
  bool HasOneRef() const { return UnderlyingHasOneRef(); }
  bool HasAtLeastOneRef() const { return UnderlyingHasAtLeastOneRef(); }

 protected:
  CefCToCppRefCounted() {}
  virtual ~CefCToCppRefCounted() {}

  // If returning the structure across the DLL boundary use Unwrap() instead.
  StructName* GetStruct() const {
    WrapperStruct* wrapperStruct = GetWrapperStruct(this);
    // Verify that the wrapper offset was calculated correctly.
    DCHECK_EQ(kWrapperType, wrapperStruct->type_);
    return wrapperStruct->struct_;
  }

 private:
  // Used to associate this wrapper object and the structure reference received
  // from the other side.
  struct WrapperStruct;

  static WrapperStruct* GetWrapperStruct(const BaseName* obj);

  // Unwrap as the derived type.
  static StructName* UnwrapDerived(CefWrapperType type, BaseName* c);

  // Increment/decrement reference counts on only the underlying class.
  NO_SANITIZE("cfi-icall")
  void UnderlyingAddRef() const {
    cef_base_ref_counted_t* base =
        reinterpret_cast<cef_base_ref_counted_t*>(GetStruct());
    if (base->add_ref)
      base->add_ref(base);
  }

  NO_SANITIZE("cfi-icall")
  bool UnderlyingRelease() const {
    cef_base_ref_counted_t* base =
        reinterpret_cast<cef_base_ref_counted_t*>(GetStruct());
    if (!base->release)
      return false;
    return base->release(base) ? true : false;
  }

  NO_SANITIZE("cfi-icall")
  bool UnderlyingHasOneRef() const {
    cef_base_ref_counted_t* base =
        reinterpret_cast<cef_base_ref_counted_t*>(GetStruct());
    if (!base->has_one_ref)
      return false;
    return base->has_one_ref(base) ? true : false;
  }

  NO_SANITIZE("cfi-icall")
  bool UnderlyingHasAtLeastOneRef() const {
    cef_base_ref_counted_t* base =
        reinterpret_cast<cef_base_ref_counted_t*>(GetStruct());
    if (!base->has_one_ref)
      return false;
    return base->has_at_least_one_ref(base) ? true : false;
  }

  CefRefCount ref_count_;

  static CefWrapperType kWrapperType;

  DISALLOW_COPY_AND_ASSIGN(CefCToCppRefCounted);
};

template <class ClassName, class BaseName, class StructName>
struct CefCToCppRefCounted<ClassName, BaseName, StructName>::WrapperStruct {
  CefWrapperType type_;
  StructName* struct_;
  ClassName wrapper_;
};

template <class ClassName, class BaseName, class StructName>
CefRefPtr<BaseName> CefCToCppRefCounted<ClassName, BaseName, StructName>::Wrap(
    StructName* s) {
  if (!s)
    return nullptr;

  // Wrap their structure with the CefCToCppRefCounted object.
  WrapperStruct* wrapperStruct = new WrapperStruct;
  wrapperStruct->type_ = kWrapperType;
  wrapperStruct->struct_ = s;

  // Put the wrapper object in a smart pointer.
  CefRefPtr<BaseName> wrapperPtr(&wrapperStruct->wrapper_);
  // Release the reference that was added to the CefCppToC wrapper object on
  // the other side before their structure was passed to us.
  wrapperStruct->wrapper_.UnderlyingRelease();
  // Return the smart pointer.
  return wrapperPtr;
}

template <class ClassName, class BaseName, class StructName>
StructName* CefCToCppRefCounted<ClassName, BaseName, StructName>::Unwrap(
    CefRefPtr<BaseName> c) {
  if (!c.get())
    return nullptr;

  WrapperStruct* wrapperStruct = GetWrapperStruct(c.get());

  // If the type does not match this object then we need to unwrap as the
  // derived type.
  if (wrapperStruct->type_ != kWrapperType)
    return UnwrapDerived(wrapperStruct->type_, c.get());

  // Add a reference to the CefCppToC wrapper object on the other side that
  // will be released once the structure is received.
  wrapperStruct->wrapper_.UnderlyingAddRef();
  // Return their original structure.
  return wrapperStruct->struct_;
}

template <class ClassName, class BaseName, class StructName>
bool CefCToCppRefCounted<ClassName, BaseName, StructName>::Release() const {
  UnderlyingRelease();
  if (ref_count_.Release()) {
    WrapperStruct* wrapperStruct = GetWrapperStruct(this);
    // Verify that the wrapper offset was calculated correctly.
    DCHECK_EQ(kWrapperType, wrapperStruct->type_);
    delete wrapperStruct;
    return true;
  }
  return false;
}

template <class ClassName, class BaseName, class StructName>
typename CefCToCppRefCounted<ClassName, BaseName, StructName>::WrapperStruct*
CefCToCppRefCounted<ClassName, BaseName, StructName>::GetWrapperStruct(
    const BaseName* obj) {
  // Offset using the WrapperStruct size instead of individual member sizes to
  // avoid problems due to platform/compiler differences in structure padding.
  return reinterpret_cast<WrapperStruct*>(
      reinterpret_cast<char*>(const_cast<BaseName*>(obj)) -
      (sizeof(WrapperStruct) - sizeof(ClassName)));
}

#endif  // CEF_LIBCEF_DLL_CTOCPP_CTOCPP_REF_COUNTED_H_
