/*
 * Copyright 2016 Hans Leidekker 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 <stdio.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "webservices.h"

#include "wine/debug.h"
#include "wine/list.h"
#include "webservices_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(webservices);

static const struct prop_desc proxy_props[] =
{
    { sizeof(ULONG), FALSE, TRUE },             /* WS_PROXY_PROPERTY_CALL_TIMEOUT */
    { sizeof(WS_MESSAGE_PROPERTIES), FALSE },   /* WS_PROXY_PROPERTY_MESSAGE_PROPERTIES */
    { sizeof(USHORT), FALSE, TRUE },            /* WS_PROXY_PROPERTY_MAX_CALL_POOL_SIZE */
    { sizeof(WS_SERVICE_PROXY_STATE), TRUE },   /* WS_PROXY_PROPERTY_STATE */
    { sizeof(ULONG), FALSE, TRUE },             /* WS_PROXY_PROPERTY_MAX_PENDING_CALLS */
    { sizeof(ULONG), FALSE, TRUE },             /* WS_PROXY_PROPERTY_MAX_CLOSE_TIMEOUT */
    { sizeof(LANGID), FALSE, TRUE },            /* WS_PROXY_FAULT_LANG_ID */
};

struct proxy
{
    WS_CHANNEL     *channel;
    ULONG           prop_count;
    struct prop     prop[sizeof(proxy_props)/sizeof(proxy_props[0])];
};

static struct proxy *alloc_proxy(void)
{
    static const ULONG count = sizeof(proxy_props)/sizeof(proxy_props[0]);
    struct proxy *ret;
    ULONG size = sizeof(*ret) + prop_size( proxy_props, count );

    if (!(ret = heap_alloc_zero( size ))) return NULL;
    prop_init( proxy_props, count, ret->prop, &ret[1] );
    ret->prop_count = count;
    return ret;
}

static void free_proxy( struct proxy *proxy )
{
    if (!proxy) return;
    WsFreeChannel( proxy->channel );
    heap_free( proxy );
}

static HRESULT create_proxy( WS_CHANNEL *channel, const WS_PROXY_PROPERTY *properties, ULONG count,
                             WS_SERVICE_PROXY **handle )
{
    struct proxy *proxy;
    HRESULT hr;
    ULONG i;

    if (!(proxy = alloc_proxy())) return E_OUTOFMEMORY;

    for (i = 0; i < count; i++)
    {
        hr = prop_set( proxy->prop, proxy->prop_count, properties[i].id, properties[i].value,
                       properties[i].valueSize );
        if (hr != S_OK)
        {
            free_proxy( proxy );
            return hr;
        }
    }

    proxy->channel = channel;

    *handle = (WS_SERVICE_PROXY *)proxy;
    return S_OK;
}

/**************************************************************************
 *          WsCreateServiceProxy		[webservices.@]
 */
HRESULT WINAPI WsCreateServiceProxy( const WS_CHANNEL_TYPE type, const WS_CHANNEL_BINDING binding,
                                     const WS_SECURITY_DESCRIPTION *desc,
                                     const WS_PROXY_PROPERTY *proxy_props, ULONG proxy_props_count,
                                     const WS_CHANNEL_PROPERTY *channel_props,
                                     const ULONG channel_props_count, WS_SERVICE_PROXY **handle,
                                     WS_ERROR *error )
{
    WS_CHANNEL *channel;
    HRESULT hr;

    TRACE( "%u %u %p %p %u %p %u %p %p\n", type, binding, desc, proxy_props, proxy_props_count,
           channel_props, channel_props_count, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (desc) FIXME( "ignoring security description\n" );

    if (!handle) return E_INVALIDARG;

    if ((hr = WsCreateChannel( type, binding, channel_props, channel_props_count, NULL, &channel,
                               NULL )) != S_OK) return hr;

    if ((hr = create_proxy( channel, proxy_props, proxy_props_count, handle )) != S_OK)
        WsFreeChannel( channel );

    return hr;
}

/**************************************************************************
 *          WsCreateServiceProxyFromTemplate		[webservices.@]
 */
HRESULT WINAPI WsCreateServiceProxyFromTemplate( WS_CHANNEL_TYPE channel_type,
                                                 const WS_PROXY_PROPERTY *properties, const ULONG count,
                                                 WS_BINDING_TEMPLATE_TYPE type, void *value, ULONG size,
                                                 const void *desc, ULONG desc_size, WS_SERVICE_PROXY **handle,
                                                 WS_ERROR *error )
{
    const WS_CHANNEL_PROPERTY *channel_props = NULL;
    ULONG channel_props_count = 0;
    WS_CHANNEL_BINDING binding;
    WS_CHANNEL *channel;
    HRESULT hr;

    TRACE( "%u %p %u %u %p %u %p %u %p %p\n", channel_type, properties, count, type, value, size, desc,
           desc_size, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!desc || !handle) return E_INVALIDARG;
    FIXME( "ignoring description\n" );

    switch (type)
    {
    case WS_HTTP_BINDING_TEMPLATE_TYPE:
    {
        WS_HTTP_BINDING_TEMPLATE *http = value;
        if (http)
        {
            channel_props = http->channelProperties.properties;
            channel_props_count = http->channelProperties.propertyCount;
        }
        binding = WS_HTTP_CHANNEL_BINDING;
        break;
    }
    case WS_HTTP_SSL_BINDING_TEMPLATE_TYPE:
    {
        WS_HTTP_SSL_BINDING_TEMPLATE *https = value;
        if (https)
        {
            channel_props = https->channelProperties.properties;
            channel_props_count = https->channelProperties.propertyCount;
        }
        binding = WS_HTTP_CHANNEL_BINDING;
        break;
    }
    default:
        FIXME( "template type %u not implemented\n", type );
        return E_NOTIMPL;
    }

    if ((hr = WsCreateChannel( channel_type, binding, channel_props, channel_props_count, NULL,
                               &channel, NULL )) != S_OK) return hr;

    if ((hr = create_proxy( channel, properties, count, handle )) != S_OK) WsFreeChannel( channel );
    return hr;
}

/**************************************************************************
 *          WsFreeServiceProxy		[webservices.@]
 */
void WINAPI WsFreeServiceProxy( WS_SERVICE_PROXY *handle )
{
    struct proxy *proxy = (struct proxy *)handle;

    TRACE( "%p\n", handle );
    free_proxy( proxy );
}

/**************************************************************************
 *          WsGetServiceProxyProperty		[webservices.@]
 */
HRESULT WINAPI WsGetServiceProxyProperty( WS_SERVICE_PROXY *handle, WS_PROXY_PROPERTY_ID id,
                                          void *buf, ULONG size, WS_ERROR *error )
{
    struct proxy *proxy = (struct proxy *)handle;

    TRACE( "%p %u %p %u %p\n", handle, id, buf, size, error );
    if (error) FIXME( "ignoring error parameter\n" );

    return prop_get( proxy->prop, proxy->prop_count, id, buf, size );
}

/**************************************************************************
 *          WsOpenServiceProxy		[webservices.@]
 */
HRESULT WINAPI WsOpenServiceProxy( WS_SERVICE_PROXY *handle, const WS_ENDPOINT_ADDRESS *endpoint,
                                   const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct proxy *proxy = (struct proxy *)handle;

    TRACE( "%p %p %p %p\n", handle, endpoint, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!handle || !endpoint) return E_INVALIDARG;
    return WsOpenChannel( proxy->channel, endpoint, NULL, NULL );
}

/**************************************************************************
 *          WsCloseServiceProxy		[webservices.@]
 */
HRESULT WINAPI WsCloseServiceProxy( WS_SERVICE_PROXY *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct proxy *proxy = (struct proxy *)handle;

    TRACE( "%p %p %p\n", handle, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!handle) return E_INVALIDARG;
    return WsCloseChannel( proxy->channel, NULL, NULL );
}

/**************************************************************************
 *          WsAbortServiceProxy		[webservices.@]
 */
HRESULT WINAPI WsAbortServiceProxy( WS_SERVICE_PROXY *handle, WS_ERROR *error )
{
    FIXME( "%p %p\n", handle, error );
    return E_NOTIMPL;
}

static HRESULT set_send_context( WS_MESSAGE *msg, const WS_CALL_PROPERTY *props, ULONG count )
{
    ULONG i;
    for (i = 0; i < count; i++)
    {
        if (props[i].id == WS_CALL_PROPERTY_SEND_MESSAGE_CONTEXT)
        {
            if (props[i].valueSize != sizeof(WS_PROXY_MESSAGE_CALLBACK_CONTEXT)) return E_INVALIDARG;
            message_set_send_context( msg, props[i].value );
            break;
        }
    }
    return S_OK;
}

static HRESULT set_receive_context( WS_MESSAGE *msg, const WS_CALL_PROPERTY *props, ULONG count )
{
    ULONG i;
    for (i = 0; i < count; i++)
    {
        if (props[i].id == WS_CALL_PROPERTY_RECEIVE_MESSAGE_CONTEXT)
        {
            if (props[i].valueSize != sizeof(WS_PROXY_MESSAGE_CALLBACK_CONTEXT)) return E_INVALIDARG;
            message_set_receive_context( msg, props[i].value );
            break;
        }
    }
    return S_OK;
}

static HRESULT write_message( WS_MESSAGE *msg, WS_XML_WRITER *writer, const WS_ELEMENT_DESCRIPTION *desc,
                              const WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args )
{
    HRESULT hr;
    message_do_send_callback( msg );
    if ((hr = WsWriteEnvelopeStart( msg, writer, NULL, NULL, NULL )) != S_OK) return hr;
    if ((hr = write_input_params( writer, desc, params, count, args )) != S_OK) return hr;
    return WsWriteEnvelopeEnd( msg, NULL );
}

static HRESULT send_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE_DESCRIPTION *desc,
                             WS_PARAMETER_DESCRIPTION *params, ULONG count, const void **args )
{
    WS_XML_WRITER *writer;
    HRESULT hr;

    if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr;
    if ((hr = WsCreateWriter( NULL, 0, &writer, NULL )) != S_OK) return hr;
    if ((hr = set_output( writer )) != S_OK) goto done;
    if ((hr = write_message( msg, writer, desc->bodyElementDescription, params, count, args )) != S_OK) goto done;
    hr = channel_send_message( channel, msg );

done:
    WsFreeWriter( writer );
    return hr;
}

static HRESULT read_message( WS_MESSAGE *msg, WS_XML_READER *reader, WS_HEAP *heap,
                             const WS_ELEMENT_DESCRIPTION *desc, const WS_PARAMETER_DESCRIPTION *params,
                             ULONG count, const void **args )
{
    HRESULT hr;
    if ((hr = WsReadEnvelopeStart( msg, reader, NULL, NULL, NULL )) != S_OK) return hr;
    message_do_receive_callback( msg );
    if ((hr = read_output_params( reader, heap, desc, params, count, args )) != S_OK) return hr;
    return WsReadEnvelopeEnd( msg, NULL );
}

static HRESULT receive_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE_DESCRIPTION *desc,
                                WS_PARAMETER_DESCRIPTION *params, ULONG count, WS_HEAP *heap, const void **args )
{
    WS_XML_READER *reader;
    char *buf;
    ULONG len;
    HRESULT hr;

    if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr;
    if ((hr = channel_receive_message( channel, &buf, &len )) != S_OK) return hr;
    if ((hr = WsCreateReader( NULL, 0, &reader, NULL )) != S_OK) goto done;
    if ((hr = set_input( reader, buf, len )) != S_OK) goto done;
    hr = read_message( msg, reader, heap, desc->bodyElementDescription, params, count, args );

done:
    WsFreeReader( reader );
    heap_free( buf);
    return hr;
}

static HRESULT create_input_message( WS_CHANNEL *channel, const WS_CALL_PROPERTY *properties,
                                     ULONG count, WS_MESSAGE **ret )
{
    WS_MESSAGE *msg;
    HRESULT hr;

    if ((hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL )) != S_OK) return hr;
    if ((hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL )) != S_OK ||
        (hr = set_send_context( msg, properties, count )) != S_OK)
    {
        WsFreeMessage( msg );
        return hr;
    }
    *ret = msg;
    return S_OK;
}

static HRESULT create_output_message( WS_CHANNEL *channel, const WS_CALL_PROPERTY *properties,
                                      ULONG count, WS_MESSAGE **ret )
{
    WS_MESSAGE *msg;
    HRESULT hr;

    if ((hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL )) != S_OK) return hr;
    if ((hr = set_receive_context( msg, properties, count )) != S_OK)
    {
        WsFreeMessage( msg );
        return hr;
    }
    *ret = msg;
    return S_OK;
}

/**************************************************************************
 *          WsCall		[webservices.@]
 */
HRESULT WINAPI WsCall( WS_SERVICE_PROXY *handle, const WS_OPERATION_DESCRIPTION *desc, const void **args,
                       WS_HEAP *heap, const WS_CALL_PROPERTY *properties, const ULONG count,
                       const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct proxy *proxy = (struct proxy *)handle;
    WS_MESSAGE *msg;
    HRESULT hr;
    ULONG i;

    TRACE( "%p %p %p %p %p %u %p %p\n", handle, desc, args, heap, properties, count, ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );
    for (i = 0; i < count; i++)
    {
        if (properties[i].id != WS_CALL_PROPERTY_SEND_MESSAGE_CONTEXT &&
            properties[i].id != WS_CALL_PROPERTY_RECEIVE_MESSAGE_CONTEXT)
        {
            FIXME( "unimplemented call property %u\n", properties[i].id );
            return E_NOTIMPL;
        }
    }

    if (!handle || !desc || (desc->parameterCount && !args)) return E_INVALIDARG;

    if ((hr = create_input_message( proxy->channel, properties, count, &msg )) != S_OK) return hr;
    hr = send_message( proxy->channel, msg, desc->inputMessageDescription, desc->parameterDescription,
                       desc->parameterCount, args );
    WsFreeMessage( msg );
    if (hr != S_OK) return hr;

    if ((hr = create_output_message( proxy->channel, properties, count, &msg )) != S_OK) return hr;
    hr = receive_message( proxy->channel, msg, desc->outputMessageDescription, desc->parameterDescription,
                          desc->parameterCount, heap, args );
    WsFreeMessage( msg );
    return hr;
}
