// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_SCRIPT_V8C_WRAPPER_PRIVATE_H_
#define COBALT_SCRIPT_V8C_WRAPPER_PRIVATE_H_

#include "base/memory/weak_ptr.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "v8/include/v8.h"

namespace cobalt {
namespace script {
namespace v8c {

// Contains private data associated with a v8::Object representing a
// JavaScript wrapper for a Cobalt platform object. There should be a one-to-
// one mapping of such v8::Object and WrapperPrivate instances, and the
// corresponding |WrapperPrivate| must be destroyed when its |v8::Object| is
// garbage collected.
class WrapperPrivate : public base::SupportsWeakPtr<WrapperPrivate> {
 public:
  // The callback that V8 will run when the |v8::Object| that we live inside
  // of dies.
  static void Callback(const v8::WeakCallbackInfo<void>& data) {
    delete reinterpret_cast<WrapperPrivate*>(data.GetParameter());
  }

  // Get the internal |WrapperPrivate*| data within |object|.  This function
  // should never be called on objects that don't have private data.
  static WrapperPrivate* GetFromWrapperObject(v8::Local<v8::Object> object) {
    DCHECK(object->InternalFieldCount() == kInternalFieldCount);
    return static_cast<WrapperPrivate*>(
        object->GetAlignedPointerFromInternalField(kInternalFieldDataIndex));
  }

  // Check whether |object| has private wrapper data.
  static bool HasWrapperPrivate(v8::Local<v8::Object> object) {
    return object->InternalFieldCount() == kInternalFieldCount;
  }

  // The total amount of internal fields in |wrapper_| we use.  See
  // |kInternalFieldDataIndex| and |kInternalFieldDummyIndex| below for
  // further information.
  static const int kInternalFieldCount = 2;

  // Start at 1009 out of paranoia that we will collide with V8 looking for
  // Blink specific class ids in the future.
  static const int kClassId = 1009;

  WrapperPrivate() = delete;
  WrapperPrivate(v8::Isolate* isolate,
                 const scoped_refptr<Wrappable>& wrappable,
                 v8::Local<v8::Object> wrapper)
      : isolate_(isolate),
        wrappable_(wrappable),
        traced_global_(isolate, wrapper) {
    wrapper->SetAlignedPointerInInternalField(kInternalFieldDataIndex, this);
    wrapper->SetAlignedPointerInInternalField(kInternalFieldDummyIndex,
                                              nullptr);
    traced_global_.SetFinalizationCallback(this, &WrapperPrivate::Callback);
    traced_global_.SetWrapperClassId(kClassId);
  }
  ~WrapperPrivate() = default;

  template <typename T>
  scoped_refptr<T> wrappable() const {
    return base::polymorphic_downcast<T*>(wrappable_.get());
  }

  Wrappable* raw_wrappable() const { return wrappable_.get(); }

  v8::Local<v8::Object> wrapper() const {
    return v8::Local<v8::Object>::Cast(traced_global_.Get(isolate_));
  }

  const v8::TracedGlobal<v8::Value>& traced_global() { return traced_global_; }

 private:
  // For the time being, we only use a single internal field, which stores a
  // pointer back to us (us being the |WrapperPrivate|).
  static const int kInternalFieldDataIndex = 0;
  // Blink uses two fields, so V8 won't believe we're a potential wrapper
  // unless we have two fields.
  //      .-""""""-.
  //    .'          '.
  //   /   O      O   \
  //  :                :
  //  |                |
  //  :    .------.    :
  //   \  '        '  /
  //    '.          .'
  //      '-......-'
  static const int kInternalFieldDummyIndex = 1;

  v8::Isolate* isolate_;
  scoped_refptr<Wrappable> wrappable_;
  v8::TracedGlobal<v8::Value> traced_global_;

  DISALLOW_COPY_AND_ASSIGN(WrapperPrivate);
};

}  // namespace v8c
}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_V8C_WRAPPER_PRIVATE_H_
