/*
 * Copyright 2016 Google Inc. 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_MOZJS_WRAPPER_FACTORY_H_
#define COBALT_SCRIPT_MOZJS_WRAPPER_FACTORY_H_

#include "base/bind.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "cobalt/base/type_id.h"
#include "cobalt/script/wrappable.h"
#include "third_party/mozjs/js/src/jsapi.h"

namespace cobalt {
namespace script {
namespace mozjs {

// Holds a mapping between Wrappable types and base::Callbacks that create
// new Wrapper objects corresponding to the Wrappable type.
// TODO: Investigate whether shared functionality with the JSC
// version can be refactored out.
class WrapperFactory : public Wrappable::CachedWrapperAccessor {
 public:
  // Callback to create a new JSObject that is a wrapper for the Wrappable.
  typedef base::Callback<JSObject*(JSContext*, const scoped_refptr<Wrappable>&)>
      CreateWrapperFunction;

  // Callback to get JSClass* of prototype.
  typedef base::Callback<const JSClass*(JSContext*)> PrototypeClassFunction;

  explicit WrapperFactory(JSContext* context) : context_(context) {}
  void RegisterWrappableType(base::TypeId wrappable_type,
                             const CreateWrapperFunction& create_function,
                             const PrototypeClassFunction& class_function);

  // Gets the Proxy for the Wrapper object for this Wrappable. It may create a
  // new Wrapper and Proxy.
  JSObject* GetWrapperProxy(const scoped_refptr<Wrappable>& wrappable) const;
  // Returns true if this JSObject is a Wrapper object.
  bool IsWrapper(JS::HandleObject wrapper) const;

  bool DoesObjectImplementInterface(JSObject*, base::TypeId) const;

 private:
  struct WrappableTypeFunctions {
    CreateWrapperFunction create_wrapper;
    PrototypeClassFunction prototype_class;
    WrappableTypeFunctions(const CreateWrapperFunction& create_wrapper,
                           const PrototypeClassFunction& prototype_class)
        : create_wrapper(create_wrapper), prototype_class(prototype_class) {}
  };

  scoped_ptr<Wrappable::WeakWrapperHandle> CreateWrapper(
      const scoped_refptr<Wrappable>& wrappable) const;

  typedef base::hash_map<base::TypeId, WrappableTypeFunctions>
      WrappableTypeFunctionsHashMap;

  JSContext* context_;
  WrappableTypeFunctionsHashMap wrappable_type_functions_;
};

}  // namespace mozjs
}  // namespace script
}  // namespace cobalt

#endif  // COBALT_SCRIPT_MOZJS_WRAPPER_FACTORY_H_
