/*
 * Copyright 2008-2009 Jacek Caban for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "dispex.h"
#include "activscp.h"

#include "resource.h"

#include "wine/unicode.h"
#include "wine/list.h"

#define JSCRIPT_ERROR 0x800A0000

typedef struct _script_ctx_t script_ctx_t;
typedef struct _exec_ctx_t exec_ctx_t;
typedef struct _dispex_prop_t dispex_prop_t;

typedef struct {
    EXCEPINFO ei;
    VARIANT var;
} jsexcept_t;

typedef struct {
    void **blocks;
    DWORD block_cnt;
    DWORD last_block;
    DWORD offset;
    BOOL mark;
    struct list custom_blocks;
} jsheap_t;

void jsheap_init(jsheap_t*);
void *jsheap_alloc(jsheap_t*,DWORD);
void *jsheap_grow(jsheap_t*,void*,DWORD,DWORD);
void jsheap_clear(jsheap_t*);
void jsheap_free(jsheap_t*);
jsheap_t *jsheap_mark(jsheap_t*);

typedef struct DispatchEx DispatchEx;

extern HINSTANCE jscript_hinstance;

#define PROPF_ARGMASK 0x00ff
#define PROPF_METHOD  0x0100
#define PROPF_ENUM    0x0200
#define PROPF_CONSTR  0x0400

/* NOTE: Keep in sync with names in Object.toString implementation */
typedef enum {
    JSCLASS_NONE,
    JSCLASS_ARRAY,
    JSCLASS_BOOLEAN,
    JSCLASS_DATE,
    JSCLASS_ERROR,
    JSCLASS_FUNCTION,
    JSCLASS_GLOBAL,
    JSCLASS_MATH,
    JSCLASS_NUMBER,
    JSCLASS_OBJECT,
    JSCLASS_REGEXP,
    JSCLASS_STRING,
    JSCLASS_ARGUMENTS
} jsclass_t;

DispatchEx *iface_to_jsdisp(IUnknown*);

typedef struct {
    union {
        IDispatch *disp;
        IDispatchEx *dispex;
        DispatchEx *jsdisp;
    } u;
    DWORD flags;
} vdisp_t;

#define VDISP_DISPEX  0x0001
#define VDISP_JSDISP  0x0002

static inline void vdisp_release(vdisp_t *vdisp)
{
    IDispatch_Release(vdisp->u.disp);
}

static inline BOOL is_jsdisp(vdisp_t *vdisp)
{
    return (vdisp->flags & VDISP_JSDISP) != 0;
}

static inline BOOL is_dispex(vdisp_t *vdisp)
{
    return (vdisp->flags & VDISP_DISPEX) != 0;
}

static inline void set_jsdisp(vdisp_t *vdisp, DispatchEx *jsdisp)
{
    vdisp->u.jsdisp = jsdisp;
    vdisp->flags = VDISP_JSDISP | VDISP_DISPEX;
    IDispatch_AddRef(vdisp->u.disp);
}

static inline void set_disp(vdisp_t *vdisp, IDispatch *disp)
{
    IDispatchEx *dispex;
    DispatchEx *jsdisp;
    HRESULT hres;

    jsdisp = iface_to_jsdisp((IUnknown*)disp);
    if(jsdisp) {
        vdisp->u.jsdisp = jsdisp;
        vdisp->flags = VDISP_JSDISP | VDISP_DISPEX;
        return;
    }

    hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
    if(SUCCEEDED(hres)) {
        vdisp->u.dispex = dispex;
        vdisp->flags = VDISP_DISPEX;
        return;
    }

    IDispatch_AddRef(disp);
    vdisp->u.disp = disp;
    vdisp->flags = 0;
}

static inline DispatchEx *get_jsdisp(vdisp_t *vdisp)
{
    return is_jsdisp(vdisp) ? vdisp->u.jsdisp : NULL;
}

typedef HRESULT (*builtin_invoke_t)(script_ctx_t*,vdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);

typedef struct {
    const WCHAR *name;
    builtin_invoke_t invoke;
    DWORD flags;
} builtin_prop_t;

typedef struct {
    jsclass_t class;
    builtin_prop_t value_prop;
    DWORD props_cnt;
    const builtin_prop_t *props;
    void (*destructor)(DispatchEx*);
    void (*on_put)(DispatchEx*,const WCHAR*);
} builtin_info_t;

struct DispatchEx {
    const IDispatchExVtbl  *lpIDispatchExVtbl;

    LONG ref;

    DWORD buf_size;
    DWORD prop_cnt;
    dispex_prop_t *props;
    script_ctx_t *ctx;

    DispatchEx *prototype;

    const builtin_info_t *builtin_info;
};

#define _IDispatchEx_(x) ((IDispatchEx*) &(x)->lpIDispatchExVtbl)

static inline void jsdisp_release(DispatchEx *jsdisp)
{
    IDispatchEx_Release(_IDispatchEx_(jsdisp));
}

HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,DispatchEx*,DispatchEx**);
HRESULT init_dispex(DispatchEx*,script_ctx_t*,const builtin_info_t*,DispatchEx*);
HRESULT init_dispex_from_constr(DispatchEx*,script_ctx_t*,const builtin_info_t*,DispatchEx*);

HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call_value(DispatchEx*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call(DispatchEx*,DISPID,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_call_name(DispatchEx*,const WCHAR*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propget(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT disp_propput(script_ctx_t*,IDispatch*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propget(DispatchEx*,DISPID,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propput_name(DispatchEx*,const WCHAR*,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propput_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propget_name(DispatchEx*,LPCWSTR,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_propget_idx(DispatchEx*,DWORD,VARIANT*,jsexcept_t*,IServiceProvider*);
HRESULT jsdisp_get_id(DispatchEx*,const WCHAR*,DWORD,DISPID*);
HRESULT jsdisp_delete_idx(DispatchEx*,DWORD);

HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
        DispatchEx*,DispatchEx**);
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,DISPPARAMS*,VARIANT*,jsexcept_t*,IServiceProvider*);

HRESULT throw_eval_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_generic_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_range_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_reference_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_regexp_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_syntax_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_type_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);
HRESULT throw_uri_error(script_ctx_t*,jsexcept_t*,UINT,const WCHAR*);

HRESULT create_object(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_math(script_ctx_t*,DispatchEx**);
HRESULT create_array(script_ctx_t*,DWORD,DispatchEx**);
HRESULT create_regexp(script_ctx_t*,const WCHAR *,int,DWORD,DispatchEx**);
HRESULT create_string(script_ctx_t*,const WCHAR*,DWORD,DispatchEx**);
HRESULT create_bool(script_ctx_t*,VARIANT_BOOL,DispatchEx**);
HRESULT create_number(script_ctx_t*,VARIANT*,DispatchEx**);

typedef enum {
    NO_HINT,
    HINT_STRING,
    HINT_NUMBER
} hint_t;

HRESULT to_primitive(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*, hint_t);
HRESULT to_boolean(VARIANT*,VARIANT_BOOL*);
HRESULT to_number(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
HRESULT to_integer(script_ctx_t*,VARIANT*,jsexcept_t*,VARIANT*);
HRESULT to_int32(script_ctx_t*,VARIANT*,jsexcept_t*,INT*);
HRESULT to_uint32(script_ctx_t*,VARIANT*,jsexcept_t*,DWORD*);
HRESULT to_string(script_ctx_t*,VARIANT*,jsexcept_t*,BSTR*);
HRESULT to_object(script_ctx_t*,VARIANT*,IDispatch**);

typedef struct named_item_t {
    IDispatch *disp;
    DWORD flags;
    LPWSTR name;

    struct named_item_t *next;
} named_item_t;

struct _script_ctx_t {
    LONG ref;

    SCRIPTSTATE state;
    exec_ctx_t *exec_ctx;
    named_item_t *named_items;
    IActiveScriptSite *site;
    IInternetHostSecurityManager *secmgr;
    DWORD safeopt;
    DWORD version;
    LCID lcid;

    jsheap_t tmp_heap;

    IDispatch *host_global;

    DispatchEx *global;
    DispatchEx *function_constr;
    DispatchEx *activex_constr;
    DispatchEx *array_constr;
    DispatchEx *bool_constr;
    DispatchEx *date_constr;
    DispatchEx *error_constr;
    DispatchEx *eval_error_constr;
    DispatchEx *range_error_constr;
    DispatchEx *reference_error_constr;
    DispatchEx *regexp_error_constr;
    DispatchEx *syntax_error_constr;
    DispatchEx *type_error_constr;
    DispatchEx *uri_error_constr;
    DispatchEx *number_constr;
    DispatchEx *object_constr;
    DispatchEx *regexp_constr;
    DispatchEx *string_constr;
};

void script_release(script_ctx_t*);

static inline void script_addref(script_ctx_t *ctx)
{
    ctx->ref++;
}

HRESULT init_global(script_ctx_t*);
HRESULT init_function_constr(script_ctx_t*,DispatchEx*);
HRESULT create_object_prototype(script_ctx_t*,DispatchEx**);

HRESULT create_activex_constr(script_ctx_t*,DispatchEx**);
HRESULT create_array_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_bool_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_date_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT init_error_constr(script_ctx_t*,DispatchEx*);
HRESULT create_number_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_object_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_regexp_constr(script_ctx_t*,DispatchEx*,DispatchEx**);
HRESULT create_string_constr(script_ctx_t*,DispatchEx*,DispatchEx**);

IUnknown *create_ax_site(script_ctx_t*);

typedef struct {
    const WCHAR *str;
    DWORD len;
} match_result_t;

HRESULT regexp_match_next(script_ctx_t*,DispatchEx*,BOOL,const WCHAR*,DWORD,const WCHAR**,match_result_t**,
        DWORD*,DWORD*,match_result_t*);
HRESULT regexp_match(script_ctx_t*,DispatchEx*,const WCHAR*,DWORD,BOOL,match_result_t**,DWORD*);
HRESULT parse_regexp_flags(const WCHAR*,DWORD,DWORD*);

static inline VARIANT *get_arg(DISPPARAMS *dp, DWORD i)
{
    return dp->rgvarg + dp->cArgs-i-1;
}

static inline DWORD arg_cnt(const DISPPARAMS *dp)
{
    return dp->cArgs - dp->cNamedArgs;
}

static inline BOOL is_class(DispatchEx *jsdisp, jsclass_t class)
{
    return jsdisp->builtin_info->class == class;
}

static inline BOOL is_vclass(vdisp_t *vdisp, jsclass_t class)
{
    return is_jsdisp(vdisp) && is_class(vdisp->u.jsdisp, class);
}

static inline BOOL is_num_vt(enum VARENUM vt)
{
    return vt == VT_I4 || vt == VT_R8;
}

static inline DOUBLE num_val(const VARIANT *v)
{
    return V_VT(v) == VT_I4 ? V_I4(v) : V_R8(v);
}

static inline void num_set_val(VARIANT *v, DOUBLE d)
{
    if(d == (DOUBLE)(INT)d) {
        V_VT(v) = VT_I4;
        V_I4(v) = d;
    }else {
        V_VT(v) = VT_R8;
        V_R8(v) = d;
    }
}

static inline void num_set_nan(VARIANT *v)
{
    V_VT(v) = VT_R8;
#ifdef NAN
    V_R8(v) = NAN;
#else
    V_UI8(v) = (ULONGLONG)0x7ff80000<<32;
#endif
}

static inline DOUBLE ret_nan(void)
{
    VARIANT v;
    num_set_nan(&v);
    return V_R8(&v);
}

static inline void num_set_inf(VARIANT *v, BOOL positive)
{
    V_VT(v) = VT_R8;
#ifdef INFINITY
    V_R8(v) = positive ? INFINITY : -INFINITY;
#else
    V_UI8(v) = (ULONGLONG)0x7ff00000<<32;
    if(!positive)
        V_R8(v) = -V_R8(v);
#endif
}

static inline DWORD make_grfdex(script_ctx_t *ctx, DWORD flags)
{
    return (ctx->version << 28) | flags;
}

const char *debugstr_variant(const VARIANT*);

HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**);

extern LONG module_ref;

static inline void lock_module(void)
{
    InterlockedIncrement(&module_ref);
}

static inline void unlock_module(void)
{
    InterlockedDecrement(&module_ref);
}

static inline void *heap_alloc(size_t len)
{
    return HeapAlloc(GetProcessHeap(), 0, len);
}

static inline void *heap_alloc_zero(size_t len)
{
    return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}

static inline void *heap_realloc(void *mem, size_t len)
{
    return HeapReAlloc(GetProcessHeap(), 0, mem, len);
}

static inline BOOL heap_free(void *mem)
{
    return HeapFree(GetProcessHeap(), 0, mem);
}

static inline LPWSTR heap_strdupW(LPCWSTR str)
{
    LPWSTR ret = NULL;

    if(str) {
        DWORD size;

        size = (strlenW(str)+1)*sizeof(WCHAR);
        ret = heap_alloc(size);
        memcpy(ret, str, size);
    }

    return ret;
}

#define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ## Vtbl)))
