/*
 * Copyright (C) 2009, 2010 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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. 
 */

#if USE(PLUGIN_HOST_PROCESS)

#ifndef ProxyInstance_h
#define ProxyInstance_h

#import "NetscapePluginInstanceProxy.h"
#import "WebKitPluginHostTypes.h"
#import <WebCore/BridgeJSC.h>
#import <WebCore/runtime_root.h>

namespace WebKit {

class ProxyClass;
    
class ProxyInstance : public JSC::Bindings::Instance {
public:
    static Ref<ProxyInstance> create(Ref<JSC::Bindings::RootObject>&& rootObject, NetscapePluginInstanceProxy* instanceProxy, uint32_t objectID)
    {
        return adoptRef(*new ProxyInstance(WTFMove(rootObject), instanceProxy, objectID));
    }
    ~ProxyInstance();

    JSC::Bindings::Method* methodNamed(JSC::PropertyName);
    JSC::Bindings::Field* fieldNamed(JSC::PropertyName);

    JSC::JSValue fieldValue(JSC::JSGlobalObject*, const JSC::Bindings::Field*) const;
    bool setFieldValue(JSC::JSGlobalObject*, const JSC::Bindings::Field*, JSC::JSValue) const;
    

    NetscapePluginInstanceProxy* instanceProxy() { return m_instanceProxy; }

    void invalidate();
    
    uint32_t objectID() const { return m_objectID; }
    
private:
    ProxyInstance(Ref<JSC::Bindings::RootObject>&&, NetscapePluginInstanceProxy*, uint32_t objectID);

    virtual JSC::Bindings::RuntimeObject* newRuntimeObject(JSC::JSGlobalObject*);

    virtual JSC::Bindings::Class* getClass() const;

    virtual JSC::JSValue getMethod(JSC::JSGlobalObject*, JSC::PropertyName);
    virtual JSC::JSValue invokeMethod(JSC::JSGlobalObject*, JSC::CallFrame*, JSC::RuntimeMethod*);

    virtual bool supportsInvokeDefaultMethod() const;
    virtual JSC::JSValue invokeDefaultMethod(JSC::JSGlobalObject*, JSC::CallFrame*);

    virtual bool supportsConstruct() const;
    virtual JSC::JSValue invokeConstruct(JSC::JSGlobalObject*, JSC::CallFrame*, const JSC::ArgList&);

    virtual JSC::JSValue defaultValue(JSC::JSGlobalObject*, JSC::PreferredPrimitiveType) const;
    virtual JSC::JSValue valueOf(JSC::JSGlobalObject*) const;
    
    virtual void getPropertyNames(JSC::JSGlobalObject*, JSC::PropertyNameArray&);

    JSC::JSValue stringValue(JSC::JSGlobalObject*) const;
    JSC::JSValue numberValue(JSC::JSGlobalObject*) const;
    JSC::JSValue booleanValue() const;
    
    JSC::JSValue invoke(JSC::JSGlobalObject*, JSC::CallFrame*, InvokeType, uint64_t identifier, const JSC::ArgList&);
    
    template <typename T>
    std::unique_ptr<T> waitForReply(uint32_t requestID) const
    {
        auto reply = m_instanceProxy->waitForReply<T>(requestID);
        
        // If the instance proxy was invalidated, just return a null reply.
        if (!m_instanceProxy)
            return nullptr;
        
        return reply;
    }

    NetscapePluginInstanceProxy* m_instanceProxy;
    uint32_t m_objectID;
    HashMap<RefPtr<StringImpl>, std::unique_ptr<JSC::Bindings::Field>> m_fields;
    HashMap<RefPtr<StringImpl>, std::unique_ptr<JSC::Bindings::Method>> m_methods;
};
    
}

#endif // ProxyInstance_h
#endif // USE(PLUGIN_HOST_PROCESS)
