/*
 * Copyright 2017 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 <stdarg.h>

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

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

WINE_DEFAULT_DEBUG_CHANNEL(webservices);

static BOOL winsock_loaded;

static BOOL WINAPI winsock_startup( INIT_ONCE *once, void *param, void **ctx )
{
    int ret;
    WSADATA data;
    if (!(ret = WSAStartup( MAKEWORD(1,1), &data ))) winsock_loaded = TRUE;
    else ERR( "WSAStartup failed: %d\n", ret );
    return TRUE;
}

void winsock_init(void)
{
    static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
    InitOnceExecuteOnce( &once, winsock_startup, NULL, NULL );
}

static const struct prop_desc listener_props[] =
{
    { sizeof(ULONG), FALSE },                               /* WS_LISTENER_PROPERTY_LISTEN_BACKLOG */
    { sizeof(WS_IP_VERSION), FALSE },                       /* WS_LISTENER_PROPERTY_IP_VERSION */
    { sizeof(WS_LISTENER_STATE), TRUE },                    /* WS_LISTENER_PROPERTY_STATE */
    { sizeof(WS_CALLBACK_MODEL), FALSE },                   /* WS_LISTENER_PROPERTY_ASYNC_CALLBACK_MODEL */
    { sizeof(WS_CHANNEL_TYPE), TRUE },                      /* WS_LISTENER_PROPERTY_CHANNEL_TYPE */
    { sizeof(WS_CHANNEL_BINDING), TRUE },                   /* WS_LISTENER_PROPERTY_CHANNEL_BINDING */
    { sizeof(ULONG), FALSE },                               /* WS_LISTENER_PROPERTY_CONNECT_TIMEOUT */
    { sizeof(BOOL), FALSE },                                /* WS_LISTENER_PROPERTY_IS_MULTICAST */
    { 0, FALSE },                                           /* WS_LISTENER_PROPERTY_MULTICAST_INTERFACES */
    { sizeof(BOOL), FALSE },                                /* WS_LISTENER_PROPERTY_MULTICAST_LOOPBACK */
    { sizeof(ULONG), FALSE },                               /* WS_LISTENER_PROPERTY_CLOSE_TIMEOUT */
    { sizeof(ULONG), FALSE },                               /* WS_LISTENER_PROPERTY_TO_HEADER_MATCHING_OPTIONS */
    { sizeof(ULONG), FALSE },                               /* WS_LISTENER_PROPERTY_TRANSPORT_URL_MATCHING_OPTIONS */
    { sizeof(WS_CUSTOM_LISTENER_CALLBACKS), FALSE },        /* WS_LISTENER_PROPERTY_CUSTOM_LISTENER_CALLBACKS */
    { 0, FALSE },                                           /* WS_LISTENER_PROPERTY_CUSTOM_LISTENER_PARAMETERS */
    { sizeof(void *), TRUE },                               /* WS_LISTENER_PROPERTY_CUSTOM_LISTENER_INSTANCE */
    { sizeof(WS_DISALLOWED_USER_AGENT_SUBSTRINGS), FALSE }  /* WS_LISTENER_PROPERTY_DISALLOWED_USER_AGENT */
};

struct listener
{
    ULONG                   magic;
    CRITICAL_SECTION        cs;
    WS_CHANNEL_TYPE         type;
    WS_CHANNEL_BINDING      binding;
    WS_LISTENER_STATE       state;
    HANDLE                  wait;
    HANDLE                  cancel;
    WS_CHANNEL             *channel;
    union
    {
        struct
        {
            SOCKET socket;
        } tcp;
        struct
        {
            SOCKET socket;
        } udp;
    } u;
    ULONG                   prop_count;
    struct prop             prop[sizeof(listener_props)/sizeof(listener_props[0])];
};

#define LISTENER_MAGIC (('L' << 24) | ('I' << 16) | ('S' << 8) | 'T')

static struct listener *alloc_listener(void)
{
    static const ULONG count = sizeof(listener_props)/sizeof(listener_props[0]);
    struct listener *ret;
    ULONG size = sizeof(*ret) + prop_size( listener_props, count );

    if (!(ret = heap_alloc_zero( size ))) return NULL;

    ret->magic = LISTENER_MAGIC;
    if (!(ret->wait = CreateEventW( NULL, FALSE, FALSE, NULL )))
    {
        heap_free( ret );
        return NULL;
    }
    if (!(ret->cancel = CreateEventW( NULL, FALSE, FALSE, NULL )))
    {
        CloseHandle( ret->wait );
        heap_free( ret );
        return NULL;
    }
    InitializeCriticalSection( &ret->cs );
    ret->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": listener.cs");

    prop_init( listener_props, count, ret->prop, &ret[1] );
    ret->prop_count = count;
    return ret;
}

static void reset_listener( struct listener *listener )
{
    listener->state = WS_LISTENER_STATE_CREATED;
    SetEvent( listener->cancel );
    listener->channel = NULL;

    switch (listener->binding)
    {
    case WS_TCP_CHANNEL_BINDING:
        closesocket( listener->u.tcp.socket );
        listener->u.tcp.socket = -1;
        break;

    case WS_UDP_CHANNEL_BINDING:
        closesocket( listener->u.udp.socket );
        listener->u.udp.socket = -1;
        break;

    default: break;
    }
}

static void free_listener( struct listener *listener )
{
    reset_listener( listener );

    CloseHandle( listener->wait );
    CloseHandle( listener->cancel );

    listener->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection( &listener->cs );
    heap_free( listener );
}

static HRESULT create_listener( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding,
                                const WS_LISTENER_PROPERTY *properties, ULONG count, struct listener **ret )
{
    struct listener *listener;
    HRESULT hr;
    ULONG i;

    if (!(listener = alloc_listener())) return E_OUTOFMEMORY;

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

    listener->type    = type;
    listener->binding = binding;

    switch (listener->binding)
    {
    case WS_TCP_CHANNEL_BINDING:
        listener->u.tcp.socket = -1;
        break;

    case WS_UDP_CHANNEL_BINDING:
        listener->u.udp.socket = -1;
        break;

    default: break;
    }

    *ret = listener;
    return S_OK;
}

/**************************************************************************
 *          WsCreateListener		[webservices.@]
 */
HRESULT WINAPI WsCreateListener( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding,
                                 const WS_LISTENER_PROPERTY *properties, ULONG count,
                                 const WS_SECURITY_DESCRIPTION *desc, WS_LISTENER **handle,
                                 WS_ERROR *error )
{
    struct listener *listener;
    HRESULT hr;

    TRACE( "%u %u %p %u %p %p %p\n", type, binding, properties, count, desc, handle, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (desc) FIXME( "ignoring security description\n" );

    if (!handle) return E_INVALIDARG;

    if (type != WS_CHANNEL_TYPE_DUPLEX_SESSION && type != WS_CHANNEL_TYPE_DUPLEX)
    {
        FIXME( "channel type %u not implemented\n", type );
        return E_NOTIMPL;
    }
    if (binding != WS_TCP_CHANNEL_BINDING && binding != WS_UDP_CHANNEL_BINDING)
    {
        FIXME( "channel binding %u not implemented\n", binding );
        return E_NOTIMPL;
    }

    if ((hr = create_listener( type, binding, properties, count, &listener )) != S_OK) return hr;

    TRACE( "created %p\n", listener );
    *handle = (WS_LISTENER *)listener;
    return S_OK;
}

/**************************************************************************
 *          WsFreeListener		[webservices.@]
 */
void WINAPI WsFreeListener( WS_LISTENER *handle )
{
    struct listener *listener = (struct listener *)handle;

    TRACE( "%p\n", handle );

    if (!listener) return;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return;
    }

    listener->magic = 0;

    LeaveCriticalSection( &listener->cs );
    free_listener( listener );
}

HRESULT resolve_hostname( const WCHAR *host, USHORT port, struct sockaddr *addr, int *addr_len, int flags )
{
    static const WCHAR fmtW[] = {'%','u',0};
    WCHAR service[6];
    ADDRINFOW hints, *res, *info;
    HRESULT hr = WS_E_ADDRESS_NOT_AVAILABLE;

    memset( &hints, 0, sizeof(hints) );
    hints.ai_flags  = flags;
    hints.ai_family = AF_INET;

    *addr_len = 0;
    sprintfW( service, fmtW, port );
    if (GetAddrInfoW( host, service, &hints, &res )) return HRESULT_FROM_WIN32( WSAGetLastError() );

    info = res;
    while (info && info->ai_family != AF_INET) info = info->ai_next;
    if (info)
    {
        memcpy( addr, info->ai_addr, info->ai_addrlen );
        *addr_len = info->ai_addrlen;
        hr = S_OK;
    }

    FreeAddrInfoW( res );
    return hr;
}

HRESULT parse_url( const WS_STRING *str, WS_URL_SCHEME_TYPE *scheme, WCHAR **host, USHORT *port )
{
    WS_HEAP *heap;
    WS_NETTCP_URL *url;
    HRESULT hr;

    if ((hr = WsCreateHeap( 1 << 8, 0, NULL, 0, &heap, NULL )) != S_OK) return hr;
    if ((hr = WsDecodeUrl( str, 0, heap, (WS_URL **)&url, NULL )) != S_OK)
    {
        WsFreeHeap( heap );
        return hr;
    }

    if (url->host.length == 1 && (url->host.chars[0] == '+' || url->host.chars[0] == '*')) *host = NULL;
    else
    {
        if (!(*host = heap_alloc( (url->host.length + 1) * sizeof(WCHAR) )))
        {
            WsFreeHeap( heap );
            return E_OUTOFMEMORY;
        }
        memcpy( *host, url->host.chars, url->host.length * sizeof(WCHAR) );
        (*host)[url->host.length] = 0;
    }
    *scheme = url->url.scheme;
    *port = url->port;

    WsFreeHeap( heap );
    return hr;
}

static HRESULT open_listener_tcp( struct listener *listener, const WS_STRING *url )
{
    struct sockaddr_storage storage;
    struct sockaddr *addr = (struct sockaddr *)&storage;
    int addr_len, on = 1;
    WS_URL_SCHEME_TYPE scheme;
    WCHAR *host;
    USHORT port;
    HRESULT hr;

    if ((hr = parse_url( url, &scheme, &host, &port )) != S_OK) return hr;
    if (scheme != WS_URL_NETTCP_SCHEME_TYPE)
    {
        heap_free( host );
        return WS_E_INVALID_ENDPOINT_URL;
    }

    winsock_init();

    hr = resolve_hostname( host, port, addr, &addr_len, AI_PASSIVE );
    heap_free( host );
    if (hr != S_OK) return hr;

    if ((listener->u.tcp.socket = socket( addr->sa_family, SOCK_STREAM, 0 )) == -1)
        return HRESULT_FROM_WIN32( WSAGetLastError() );

    if (setsockopt( listener->u.tcp.socket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on) ) < 0)
    {
        closesocket( listener->u.tcp.socket );
        listener->u.tcp.socket = -1;
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }

    if (bind( listener->u.tcp.socket, addr, addr_len ) < 0)
    {
        closesocket( listener->u.tcp.socket );
        listener->u.tcp.socket = -1;
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }

    if (listen( listener->u.tcp.socket, 0 ) < 0)
    {
        closesocket( listener->u.tcp.socket );
        listener->u.tcp.socket = -1;
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }

    listener->state = WS_LISTENER_STATE_OPEN;
    return S_OK;
}

static HRESULT open_listener_udp( struct listener *listener, const WS_STRING *url )
{
    struct sockaddr_storage storage;
    struct sockaddr *addr = (struct sockaddr *)&storage;
    int addr_len;
    WS_URL_SCHEME_TYPE scheme;
    WCHAR *host;
    USHORT port;
    HRESULT hr;

    if ((hr = parse_url( url, &scheme, &host, &port )) != S_OK) return hr;
    if (scheme != WS_URL_SOAPUDP_SCHEME_TYPE)
    {
        heap_free( host );
        return WS_E_INVALID_ENDPOINT_URL;
    }

    winsock_init();

    hr = resolve_hostname( host, port, addr, &addr_len, AI_PASSIVE );
    heap_free( host );
    if (hr != S_OK) return hr;

    if ((listener->u.udp.socket = socket( addr->sa_family, SOCK_DGRAM, 0 )) == -1)
        return HRESULT_FROM_WIN32( WSAGetLastError() );

    if (bind( listener->u.udp.socket, addr, addr_len ) < 0)
    {
        closesocket( listener->u.udp.socket );
        listener->u.udp.socket = -1;
        return HRESULT_FROM_WIN32( WSAGetLastError() );
    }

    listener->state = WS_LISTENER_STATE_OPEN;
    return S_OK;
}

static HRESULT open_listener( struct listener *listener, const WS_STRING *url )
{
    switch (listener->binding)
    {
    case WS_TCP_CHANNEL_BINDING:
        return open_listener_tcp( listener, url );

    case WS_UDP_CHANNEL_BINDING:
        return open_listener_udp( listener, url );

    default:
        ERR( "unhandled binding %u\n", listener->binding );
        return E_NOTIMPL;
    }
}

/**************************************************************************
 *          WsOpenListener		[webservices.@]
 */
HRESULT WINAPI WsOpenListener( WS_LISTENER *handle, WS_STRING *url, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct listener *listener = (struct listener *)handle;
    HRESULT hr;

    TRACE( "%p %s %p %p\n", handle, url ? debugstr_wn(url->chars, url->length) : "null", ctx, error );
    if (error) FIXME( "ignoring error parameter\n" );
    if (ctx) FIXME( "ignoring ctx parameter\n" );

    if (!listener || !url) return E_INVALIDARG;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return E_INVALIDARG;
    }

    if (listener->state != WS_LISTENER_STATE_CREATED)
    {
        LeaveCriticalSection( &listener->cs );
        return WS_E_INVALID_OPERATION;
    }

    hr = open_listener( listener, url );

    LeaveCriticalSection( &listener->cs );
    return hr;
}

static void close_listener( struct listener *listener )
{
    reset_listener( listener );
    listener->state = WS_LISTENER_STATE_CLOSED;
}

/**************************************************************************
 *          WsCloseListener		[webservices.@]
 */
HRESULT WINAPI WsCloseListener( WS_LISTENER *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
{
    struct listener *listener = (struct listener *)handle;

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

    if (!listener) return E_INVALIDARG;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return E_INVALIDARG;
    }

    close_listener( listener );

    LeaveCriticalSection( &listener->cs );
    return S_OK;
}

/**************************************************************************
 *          WsResetListener		[webservices.@]
 */
HRESULT WINAPI WsResetListener( WS_LISTENER *handle, WS_ERROR *error )
{
    struct listener *listener = (struct listener *)handle;

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

    if (!listener) return E_INVALIDARG;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return E_INVALIDARG;
    }

    if (listener->state != WS_LISTENER_STATE_CREATED && listener->state != WS_LISTENER_STATE_CLOSED)
    {
        LeaveCriticalSection( &listener->cs );
        return WS_E_INVALID_OPERATION;
    }

    reset_listener( listener );

    LeaveCriticalSection( &listener->cs );
    return S_OK;
}

/**************************************************************************
 *          WsGetListenerProperty		[webservices.@]
 */
HRESULT WINAPI WsGetListenerProperty( WS_LISTENER *handle, WS_LISTENER_PROPERTY_ID id, void *buf,
                                      ULONG size, WS_ERROR *error )
{
    struct listener *listener = (struct listener *)handle;
    HRESULT hr = S_OK;

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

    if (!listener) return E_INVALIDARG;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return E_INVALIDARG;
    }

    switch (id)
    {
    case WS_LISTENER_PROPERTY_STATE:
        if (!buf || size != sizeof(listener->state)) hr = E_INVALIDARG;
        else *(WS_LISTENER_STATE *)buf = listener->state;
        break;

    case WS_LISTENER_PROPERTY_CHANNEL_TYPE:
        if (!buf || size != sizeof(listener->type)) hr = E_INVALIDARG;
        else *(WS_CHANNEL_TYPE *)buf = listener->type;
        break;

    case WS_LISTENER_PROPERTY_CHANNEL_BINDING:
        if (!buf || size != sizeof(listener->binding)) hr = E_INVALIDARG;
        else *(WS_CHANNEL_BINDING *)buf = listener->binding;
        break;

    default:
        hr = prop_get( listener->prop, listener->prop_count, id, buf, size );
    }

    LeaveCriticalSection( &listener->cs );
    return hr;
}

/**************************************************************************
 *          WsSetListenerProperty		[webservices.@]
 */
HRESULT WINAPI WsSetListenerProperty( WS_LISTENER *handle, WS_LISTENER_PROPERTY_ID id, const void *value,
                                      ULONG size, WS_ERROR *error )
{
    struct listener *listener = (struct listener *)handle;
    HRESULT hr;

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

    if (!listener) return E_INVALIDARG;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return E_INVALIDARG;
    }

    hr = prop_set( listener->prop, listener->prop_count, id, value, size );

    LeaveCriticalSection( &listener->cs );
    return hr;
}

/**************************************************************************
 *          WsAcceptChannel		[webservices.@]
 */
HRESULT WINAPI WsAcceptChannel( WS_LISTENER *handle, WS_CHANNEL *channel_handle, const WS_ASYNC_CONTEXT *ctx,
                                WS_ERROR *error )
{
    struct listener *listener = (struct listener *)handle;
    HRESULT hr = E_NOTIMPL;
    HANDLE wait, cancel;

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

    if (!listener || !channel_handle) return E_INVALIDARG;

    EnterCriticalSection( &listener->cs );

    if (listener->magic != LISTENER_MAGIC)
    {
        LeaveCriticalSection( &listener->cs );
        return E_INVALIDARG;
    }

    if (listener->state != WS_LISTENER_STATE_OPEN || listener->channel)
    {
        LeaveCriticalSection( &listener->cs );
        return WS_E_INVALID_OPERATION;
    }

    wait = listener->wait;
    cancel = listener->cancel;
    listener->channel = channel_handle;

    switch (listener->binding)
    {
    case WS_TCP_CHANNEL_BINDING:
    {
        SOCKET socket = listener->u.tcp.socket;

        LeaveCriticalSection( &listener->cs );
        return channel_accept_tcp( socket, wait, cancel, channel_handle );
    }
    case WS_UDP_CHANNEL_BINDING:
    {
        SOCKET socket = listener->u.udp.socket;

        LeaveCriticalSection( &listener->cs );
        return channel_accept_udp( socket, wait, cancel, channel_handle );
    }
    default:
        FIXME( "listener binding %u not supported\n", listener->binding );
        break;
    }

    LeaveCriticalSection( &listener->cs );
    return hr;
}
