/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 * Copyright (C) 2009 Pawel Hajdan (phajdan.jr@chromium.org)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
  CppBoundClass class:
  This base class serves as a parent for C++ classes designed to be bound to
  JavaScript objects.

  Subclasses should define the constructor to build the property and method
  lists needed to bind this class to a JS object.  They should also declare
  and define member variables and methods to be exposed to JS through
  that object.
*/

#ifndef CppBoundClass_h
#define CppBoundClass_h

#include "CppVariant.h"
#include "public/platform/WebNonCopyable.h"
#include <map>
#include <memory>
#include <vector>

namespace WebKit {
class WebFrame;
class WebString;
}

namespace WebTestRunner {

typedef std::vector<CppVariant> CppArgumentList;

// CppBoundClass lets you map Javascript method calls and property accesses
// directly to C++ method calls and CppVariant* variable access.
class CppBoundClass : public WebKit::WebNonCopyable {
public:
    class PropertyCallback {
    public:
        virtual ~PropertyCallback() { }

        // Sets |value| to the value of the property. Returns false in case of
        // failure. |value| is always non-0.
        virtual bool getValue(CppVariant* result) = 0;

        // sets the property value to |value|. Returns false in case of failure.
        virtual bool setValue(const CppVariant&) = 0;
    };

    // Callback class for "void function(CppVariant*)"
    class GetterCallback {
    public:
        virtual ~GetterCallback() { }
        virtual void run(CppVariant*) = 0;
    };

    // The constructor should call BindMethod, BindProperty, and
    // SetFallbackMethod as needed to set up the methods, properties, and
    // fallback method.
    CppBoundClass() : m_boundToFrame(false) { }
    virtual ~CppBoundClass();

    // Return a CppVariant representing this class, for use with BindProperty().
    // The variant type is guaranteed to be NPVariantType_Object.
    CppVariant* getAsCppVariant();

    // Given a WebFrame, BindToJavascript builds the NPObject that will represent
    // the class and binds it to the frame's window under the given name. This
    // should generally be called from the WebView delegate's
    // WindowObjectCleared(). A class so bound will be accessible to JavaScript
    // as window.<classname>. The owner of the CppBoundObject is responsible for
    // keeping the object around while the frame is alive, and for destroying it
    // afterwards.
    void bindToJavascript(WebKit::WebFrame*, const WebKit::WebString& classname);

    // Used by a test. Returns true if a method with the specified name exists,
    // regardless of whether a fallback is registered.
    bool isMethodRegistered(const std::string&) const;

protected:
    // Callback for "void function(const CppArguemntList&, CppVariant*)"
    class Callback {
    public:
        virtual ~Callback() { }
        virtual void run(const CppArgumentList&, CppVariant*) = 0;
    };

    // Callback for "void T::method(const CppArguemntList&, CppVariant*)"
    template <class T> class MemberCallback : public Callback {
    public:
        typedef void (T::*MethodType)(const CppArgumentList&, CppVariant*);
        MemberCallback(T* object, MethodType method)
            : m_object(object)
            , m_method(method) { }
        virtual ~MemberCallback() { }

        virtual void run(const CppArgumentList& arguments, CppVariant* result)
        {
            (m_object->*m_method)(arguments, result);
        }

    private:
        T* m_object;
        MethodType m_method;
    };

    // Callback class for "void T::method(CppVariant*)"
    template <class T> class MemberGetterCallback : public GetterCallback {
    public:
        typedef void (T::*MethodType)(CppVariant*);
        MemberGetterCallback(T* object, MethodType method)
            : m_object(object)
            , m_method(method) { }
        virtual ~MemberGetterCallback() { }

        virtual void run(CppVariant* result) { (m_object->*m_method)(result); }

    private:
        T* m_object;
        MethodType m_method;
    };

    // Bind the Javascript method called the string parameter to the C++ method.
    void bindCallback(const std::string&, Callback*);

    // A wrapper for bindCallback, to simplify the common case of binding a
    // method on the current object. Though not verified here, the method parameter
    // must be a method of this CppBoundClass subclass.
    template<class T>
    void bindMethod(const std::string& name, void (T::*method)(const CppArgumentList&, CppVariant*))
    {
        Callback* callback = new MemberCallback<T>(static_cast<T*>(this), method);
        bindCallback(name, callback);
    }

    // Bind Javascript property |name| to the C++ getter callback |callback|.
    // This can be used to create read-only properties.
    void bindGetterCallback(const std::string&, std::auto_ptr<GetterCallback>);

    // A wrapper for BindGetterCallback, to simplify the common case of binding a
    // property on the current object. Though not verified here, the method parameter
    // must be a method of this CppBoundClass subclass.
    template<class T>
    void bindProperty(const std::string& name, void (T::*method)(CppVariant*))
    {
        std::auto_ptr<GetterCallback> callback(new MemberGetterCallback<T>(static_cast<T*>(this), method));
        bindGetterCallback(name, callback);
    }

    // Bind the Javascript property called |name| to a CppVariant.
    void bindProperty(const std::string&, CppVariant*);

    // Bind Javascript property called |name| to a PropertyCallback.
    // CppBoundClass assumes control over the life time of the callback.
    void bindProperty(const std::string&, PropertyCallback*);

    // Set the fallback callback, which is called when when a callback is
    // invoked that isn't bound.
    // If it is 0 (its default value), a JavaScript exception is thrown in
    // that case (as normally expected). If non 0, the fallback method is
    // invoked and the script continues its execution.
    // Passing 0 clears out any existing binding.
    // It is used for tests and should probably only be used in such cases
    // as it may cause unexpected behaviors (a JavaScript object with a
    // fallback always returns true when checked for a method's
    // existence).
    void bindFallbackCallback(std::auto_ptr<Callback> fallbackCallback)
    {
        m_fallbackCallback = fallbackCallback;
    }

    // A wrapper for BindFallbackCallback, to simplify the common case of
    // binding a method on the current object. Though not verified here,
    // |method| must be a method of this CppBoundClass subclass.
    // Passing 0 for |method| clears out any existing binding.
    template<class T>
    void bindFallbackMethod(void (T::*method)(const CppArgumentList&, CppVariant*))
    {
        if (method)
            bindFallbackCallback(std::auto_ptr<Callback>(new MemberCallback<T>(static_cast<T*>(this), method)));
        else
            bindFallbackCallback(std::auto_ptr<Callback>());
    }

    // Some fields are protected because some tests depend on accessing them,
    // but otherwise they should be considered private.

    typedef std::map<NPIdentifier, PropertyCallback*> PropertyList;
    typedef std::map<NPIdentifier, Callback*> MethodList;
    // These maps associate names with property and method pointers to be
    // exposed to JavaScript.
    PropertyList m_properties;
    MethodList m_methods;

    // The callback gets invoked when a call is made to an nonexistent method.
    std::auto_ptr<Callback> m_fallbackCallback;

private:
    // NPObject callbacks.
    friend struct CppNPObject;
    bool hasMethod(NPIdentifier) const;
    bool invoke(NPIdentifier, const NPVariant* args, size_t argCount,
                NPVariant* result);
    bool hasProperty(NPIdentifier) const;
    bool getProperty(NPIdentifier, NPVariant* result) const;
    bool setProperty(NPIdentifier, const NPVariant*);

    // A lazily-initialized CppVariant representing this class. We retain 1
    // reference to this object, and it is released on deletion.
    CppVariant m_selfVariant;

    // True if our np_object has been bound to a WebFrame, in which case it must
    // be unregistered with V8 when we delete it.
    bool m_boundToFrame;
};

}

#endif // CppBoundClass_h
