/*
 * Copyright 2009 Piotr Caban
 *
 * 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 "config.h"
#include "wine/port.h"

#include <math.h>

#include "jscript.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(jscript);

static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
static const WCHAR messageW[] = {'m','e','s','s','a','g','e',0};
static const WCHAR nameW[] = {'n','a','m','e',0};
static const WCHAR numberW[] = {'n','u','m','b','e','r',0};
static const WCHAR toStringW[] = {'t','o','S','t','r','i','n','g',0};

/* ECMA-262 3rd Edition    15.11.4.4 */
static HRESULT Error_toString(script_ctx_t *ctx, vdisp_t *vthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
    jsdisp_t *jsthis;
    BSTR name = NULL, msg = NULL, ret = NULL;
    VARIANT v;
    HRESULT hres;

    static const WCHAR object_errorW[] = {'[','o','b','j','e','c','t',' ','E','r','r','o','r',']',0};

    TRACE("\n");

    jsthis = get_jsdisp(vthis);
    if(!jsthis || ctx->version < 2) {
        if(retv) {
            V_VT(retv) = VT_BSTR;
            V_BSTR(retv) = SysAllocString(object_errorW);
            if(!V_BSTR(retv))
                return E_OUTOFMEMORY;
        }
        return S_OK;
    }

    hres = jsdisp_propget_name(jsthis, nameW, &v, ei, caller);
    if(FAILED(hres))
        return hres;

    if(V_VT(&v) != VT_EMPTY) {
        hres = to_string(ctx, &v, ei, &name);
        VariantClear(&v);
        if(FAILED(hres))
            return hres;
        if(!*name) {
            SysFreeString(name);
            name = NULL;
        }
    }

    hres = jsdisp_propget_name(jsthis, messageW, &v, ei, caller);
    if(SUCCEEDED(hres)) {
        if(V_VT(&v) != VT_EMPTY) {
            hres = to_string(ctx, &v, ei, &msg);
            VariantClear(&v);
            if(SUCCEEDED(hres) && !*msg) {
                SysFreeString(msg);
                msg = NULL;
            }
        }
    }

    if(SUCCEEDED(hres)) {
        if(name && msg) {
            DWORD name_len, msg_len;

            name_len = SysStringLen(name);
            msg_len = SysStringLen(msg);

            ret = SysAllocStringLen(NULL, name_len + msg_len + 2);
            if(ret) {
                memcpy(ret, name, name_len*sizeof(WCHAR));
                ret[name_len] = ':';
                ret[name_len+1] = ' ';
                memcpy(ret+name_len+2, msg, msg_len*sizeof(WCHAR));
            }
        }else if(name) {
            ret = name;
            name = NULL;
        }else if(msg) {
            ret = msg;
            msg = NULL;
        }else {
            ret = SysAllocString(object_errorW);
            if(!V_BSTR(retv))
                hres = E_OUTOFMEMORY;
        }
    }

    SysFreeString(msg);
    SysFreeString(name);
    if(FAILED(hres))
        return hres;
    if(!ret)
        return E_OUTOFMEMORY;

    if(retv) {
        V_VT(retv) = VT_BSTR;
        V_BSTR(retv) = ret;
    }else {
        SysFreeString(ret);
    }

    return S_OK;
}

static HRESULT Error_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");

    switch(flags) {
    case INVOKE_FUNC:
        return throw_type_error(ctx, ei, IDS_NOT_FUNC, NULL);
    default:
        FIXME("unimplemented flags %x\n", flags);
        return E_NOTIMPL;
    }

    return S_OK;
}

static const builtin_prop_t Error_props[] = {
    {toStringW,                 Error_toString,                     PROPF_METHOD}
};

static const builtin_info_t Error_info = {
    JSCLASS_ERROR,
    {NULL, Error_value, 0},
    sizeof(Error_props)/sizeof(*Error_props),
    Error_props,
    NULL,
    NULL
};

static const builtin_info_t ErrorInst_info = {
    JSCLASS_ERROR,
    {NULL, Error_value, 0},
    0,
    NULL,
    NULL,
    NULL
};

static HRESULT alloc_error(script_ctx_t *ctx, jsdisp_t *prototype,
        jsdisp_t *constr, jsdisp_t **ret)
{
    jsdisp_t *err;
    HRESULT hres;

    err = heap_alloc_zero(sizeof(*err));
    if(!err)
        return E_OUTOFMEMORY;

    if(prototype)
        hres = init_dispex(err, ctx, &Error_info, prototype);
    else
        hres = init_dispex_from_constr(err, ctx, &ErrorInst_info,
            constr ? constr : ctx->error_constr);
    if(FAILED(hres)) {
        heap_free(err);
        return hres;
    }

    *ret = err;
    return S_OK;
}

static HRESULT create_error(script_ctx_t *ctx, jsdisp_t *constr,
        UINT number, const WCHAR *msg, jsdisp_t **ret)
{
    jsdisp_t *err;
    VARIANT v;
    HRESULT hres;

    hres = alloc_error(ctx, NULL, constr, &err);
    if(FAILED(hres))
        return hres;

    V_VT(&v) = VT_I4;
    V_I4(&v) = number;
    hres = jsdisp_propput_name(err, numberW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
    if(FAILED(hres)) {
        jsdisp_release(err);
        return hres;
    }

    V_VT(&v) = VT_BSTR;
    if(msg) V_BSTR(&v) = SysAllocString(msg);
    else V_BSTR(&v) = SysAllocStringLen(NULL, 0);
    if(V_BSTR(&v)) {
        hres = jsdisp_propput_name(err, messageW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
        if(SUCCEEDED(hres))
            hres = jsdisp_propput_name(err, descriptionW, &v, NULL/*FIXME*/, NULL/*FIXME*/);
        SysFreeString(V_BSTR(&v));
    }else {
        hres = E_OUTOFMEMORY;
    }
    if(FAILED(hres)) {
        jsdisp_release(err);
        return hres;
    }

    *ret = err;
    return S_OK;
}

static HRESULT error_constr(script_ctx_t *ctx, WORD flags, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei, jsdisp_t *constr) {
    jsdisp_t *err;
    UINT num = 0;
    BSTR msg = NULL;
    HRESULT hres;

    if(arg_cnt(dp)) {
        VARIANT numv;

        hres = to_number(ctx, get_arg(dp, 0), ei, &numv);
        if(FAILED(hres) || (V_VT(&numv)==VT_R8 && isnan(V_R8(&numv))))
            hres = to_string(ctx, get_arg(dp, 0), ei, &msg);
        else if(V_VT(&numv) == VT_I4)
            num = V_I4(&numv);
        else
            num = V_R8(&numv);

        if(FAILED(hres))
            return hres;
    }

    if(arg_cnt(dp)>1 && !msg) {
        hres = to_string(ctx, get_arg(dp, 1), ei, &msg);
        if(FAILED(hres))
            return hres;
    }

    switch(flags) {
    case INVOKE_FUNC:
    case DISPATCH_CONSTRUCT:
        hres = create_error(ctx, constr, num, msg, &err);
        SysFreeString(msg);

        if(FAILED(hres))
            return hres;

        if(retv)
            var_set_jsdisp(retv, err);
        else
            jsdisp_release(err);

        return S_OK;

    default:
        FIXME("unimplemented flags %x\n", flags);
        return E_NOTIMPL;
    }
}

static HRESULT ErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->error_constr);
}

static HRESULT EvalErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->eval_error_constr);
}

static HRESULT RangeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->range_error_constr);
}

static HRESULT ReferenceErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->reference_error_constr);
}

static HRESULT RegExpErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->regexp_error_constr);
}

static HRESULT SyntaxErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->syntax_error_constr);
}

static HRESULT TypeErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->type_error_constr);
}

static HRESULT URIErrorConstr_value(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags,
        DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp)
{
    TRACE("\n");
    return error_constr(ctx, flags, dp, retv, ei, ctx->uri_error_constr);
}

HRESULT init_error_constr(script_ctx_t *ctx, jsdisp_t *object_prototype)
{
    static const WCHAR ErrorW[] = {'E','r','r','o','r',0};
    static const WCHAR EvalErrorW[] = {'E','v','a','l','E','r','r','o','r',0};
    static const WCHAR RangeErrorW[] = {'R','a','n','g','e','E','r','r','o','r',0};
    static const WCHAR ReferenceErrorW[] = {'R','e','f','e','r','e','n','c','e','E','r','r','o','r',0};
    static const WCHAR RegExpErrorW[] = {'R','e','g','E','x','p','E','r','r','o','r',0};
    static const WCHAR SyntaxErrorW[] = {'S','y','n','t','a','x','E','r','r','o','r',0};
    static const WCHAR TypeErrorW[] = {'T','y','p','e','E','r','r','o','r',0};
    static const WCHAR URIErrorW[] = {'U','R','I','E','r','r','o','r',0};
    static const WCHAR *names[] = {ErrorW, EvalErrorW, RangeErrorW,
        ReferenceErrorW, RegExpErrorW, SyntaxErrorW, TypeErrorW, URIErrorW};
    jsdisp_t **constr_addr[] = {&ctx->error_constr, &ctx->eval_error_constr,
        &ctx->range_error_constr, &ctx->reference_error_constr, &ctx->regexp_error_constr,
        &ctx->syntax_error_constr, &ctx->type_error_constr,
        &ctx->uri_error_constr};
    static builtin_invoke_t constr_val[] = {ErrorConstr_value, EvalErrorConstr_value,
        RangeErrorConstr_value, ReferenceErrorConstr_value, RegExpErrorConstr_value,
        SyntaxErrorConstr_value, TypeErrorConstr_value, URIErrorConstr_value};

    jsdisp_t *err;
    INT i;
    VARIANT v;
    HRESULT hres;

    for(i=0; i < sizeof(names)/sizeof(names[0]); i++) {
        hres = alloc_error(ctx, i==0 ? object_prototype : NULL, NULL, &err);
        if(FAILED(hres))
            return hres;

        V_VT(&v) = VT_BSTR;
        V_BSTR(&v) = SysAllocString(names[i]);
        if(!V_BSTR(&v)) {
            jsdisp_release(err);
            return E_OUTOFMEMORY;
        }

        hres = jsdisp_propput_name(err, nameW, &v, NULL/*FIXME*/, NULL/*FIXME*/);

        if(SUCCEEDED(hres))
            hres = create_builtin_function(ctx, constr_val[i], names[i], NULL,
                    PROPF_CONSTR|1, err, constr_addr[i]);

        jsdisp_release(err);
        VariantClear(&v);
        if(FAILED(hres))
            return hres;
    }

    return S_OK;
}

static HRESULT throw_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str, jsdisp_t *constr)
{
    WCHAR buf[1024], *pos = NULL;
    jsdisp_t *err;
    HRESULT hres;

    buf[0] = '\0';
    LoadStringW(jscript_hinstance, id&0xFFFF,  buf, sizeof(buf)/sizeof(WCHAR));

    if(str) pos = strchrW(buf, '|');
    if(pos) {
        int len = strlenW(str);
        memmove(pos+len, pos+1, (strlenW(pos+1)+1)*sizeof(WCHAR));
        memcpy(pos, str, len*sizeof(WCHAR));
    }

    WARN("%s\n", debugstr_w(buf));

    id |= JSCRIPT_ERROR;
    hres = create_error(ctx, constr, id, buf, &err);
    if(FAILED(hres))
        return hres;

    if(ei)
        var_set_jsdisp(&ei->var, err);
    return id;
}

HRESULT throw_generic_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->error_constr);
}

HRESULT throw_range_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->range_error_constr);
}

HRESULT throw_reference_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->reference_error_constr);
}

HRESULT throw_regexp_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->regexp_error_constr);
}

HRESULT throw_syntax_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->syntax_error_constr);
}

HRESULT throw_type_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->type_error_constr);
}

HRESULT throw_uri_error(script_ctx_t *ctx, jsexcept_t *ei, UINT id, const WCHAR *str)
{
    return throw_error(ctx, ei, id, str, ctx->uri_error_constr);
}
