/*
 * Web Services on Devices
 *
 * Copyright 2017 Owen Rudge 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>

#define COBJMACROS

#include "winsock2.h"
#include "ws2tcpip.h"
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
#include "wsdapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);

typedef struct IWSDUdpAddressImpl {
    IWSDUdpAddress IWSDUdpAddress_iface;
    LONG           ref;
    SOCKADDR_STORAGE sockAddr;
    WCHAR            ipv4Address[25];
    WCHAR            ipv6Address[64];
    WORD             port;
    WSDUdpMessageType messageType;
} IWSDUdpAddressImpl;

static inline IWSDUdpAddressImpl *impl_from_IWSDUdpAddress(IWSDUdpAddress *iface)
{
    return CONTAINING_RECORD(iface, IWSDUdpAddressImpl, IWSDUdpAddress_iface);
}

static HRESULT WINAPI IWSDUdpAddressImpl_QueryInterface(IWSDUdpAddress *iface, REFIID riid, void **ppv)
{
    IWSDUdpAddressImpl *This = impl_from_IWSDUdpAddress(iface);

    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppv);

    if (!ppv)
    {
        WARN("Invalid parameter\n");
        return E_INVALIDARG;
    }

    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IWSDUdpAddress) ||
        IsEqualIID(riid, &IID_IWSDTransportAddress) ||
        IsEqualIID(riid, &IID_IWSDAddress))
    {
        *ppv = &This->IWSDUdpAddress_iface;
    }
    else
    {
        WARN("Unknown IID %s\n", debugstr_guid(riid));
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI IWSDUdpAddressImpl_AddRef(IWSDUdpAddress *iface)
{
    IWSDUdpAddressImpl *This = impl_from_IWSDUdpAddress(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);
    return ref;
}

static ULONG WINAPI IWSDUdpAddressImpl_Release(IWSDUdpAddress *iface)
{
    IWSDUdpAddressImpl *This = impl_from_IWSDUdpAddress(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if (ref == 0)
    {
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI IWSDUdpAddressImpl_Serialize(IWSDUdpAddress *This, LPWSTR pszBuffer, DWORD cchLength, BOOL fSafe)
{
    FIXME("(%p, %p, %d, %d)\n", This, pszBuffer, cchLength, fSafe);
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_Deserialize(IWSDUdpAddress *This, LPCWSTR pszBuffer)
{
    FIXME("(%p, %s)\n", This, debugstr_w(pszBuffer));
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetPort(IWSDUdpAddress *This, WORD *pwPort)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);

    TRACE("(%p, %p)\n", This, pwPort);

    if (pwPort == NULL)
    {
        return E_POINTER;
    }

    *pwPort = impl->port;
    return S_OK;
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetPort(IWSDUdpAddress *This, WORD wPort)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);

    TRACE("(%p, %d)\n", This, wPort);

    impl->port = wPort;
    return S_OK;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetTransportAddressEx(IWSDUdpAddress *This, BOOL fSafe, LPCWSTR *ppszAddress)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
    SOCKADDR_STORAGE storage;
    DWORD size;

    TRACE("(%p, %d, %p)\n", This, fSafe, ppszAddress);

    if (ppszAddress == NULL)
        return E_POINTER;

    *ppszAddress = NULL;

    switch (((SOCKADDR_IN *) &impl->sockAddr)->sin_family)
    {
        case AF_INET:
            size = sizeof(impl->ipv4Address) / sizeof(WCHAR);

            if (WSAAddressToStringW((LPSOCKADDR) &impl->sockAddr, sizeof(SOCKADDR_IN), NULL, impl->ipv4Address, &size) == 0)
            {
                *ppszAddress = impl->ipv4Address;
                return S_OK;
            }

            break;

        case AF_INET6:
            size = sizeof(impl->ipv6Address) / sizeof(WCHAR);

            /* Copy the SOCKADDR structure so we can remove the scope ID if not required */
            memcpy(&storage, &impl->sockAddr, sizeof(SOCKADDR_IN6));

            if (!fSafe)
                ((SOCKADDR_IN6 *) &storage)->sin6_scope_id = 0;

            if (WSAAddressToStringW((LPSOCKADDR) &storage, sizeof(SOCKADDR_IN6), NULL, impl->ipv6Address, &size) == 0)
            {
                *ppszAddress = impl->ipv6Address;
                return S_OK;
            }

            break;

        default:
            return S_OK;
    }

    return HRESULT_FROM_WIN32(WSAGetLastError());
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetTransportAddress(IWSDUdpAddress *This, LPCWSTR *ppszAddress)
{
    return IWSDUdpAddressImpl_GetTransportAddressEx(This, FALSE, ppszAddress);
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetTransportAddress(IWSDUdpAddress *This, LPCWSTR pszAddress)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
    ADDRINFOW *addrInfo = NULL;
    ADDRINFOW hints;
    int ret;

    TRACE("(%p, %s)\n", impl, debugstr_w(pszAddress));

    if (pszAddress == NULL)
        return E_INVALIDARG;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = AF_UNSPEC;

    ret = GetAddrInfoW(pszAddress, NULL, &hints, &addrInfo);

    if (ret == 0)
    {
        ZeroMemory(&impl->sockAddr, sizeof(SOCKADDR_STORAGE));
        memcpy(&impl->sockAddr, addrInfo->ai_addr, addrInfo->ai_addrlen);
    }

    if (addrInfo != NULL)
        FreeAddrInfoW(addrInfo);

    return HRESULT_FROM_WIN32(ret);
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetSockaddr(IWSDUdpAddress *This, const SOCKADDR_STORAGE *pSockAddr)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);

    TRACE("(%p, %p)\n", This, pSockAddr);

    if (pSockAddr == NULL)
    {
        return E_POINTER;
    }

    memcpy(&impl->sockAddr, pSockAddr, sizeof(SOCKADDR_STORAGE));
    return S_OK;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetSockaddr(IWSDUdpAddress *This, SOCKADDR_STORAGE *pSockAddr)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);
    SOCKADDR_IN *sockAddr = (SOCKADDR_IN *) &impl->sockAddr;

    TRACE("(%p, %p)\n", This, pSockAddr);

    if (pSockAddr == NULL)
    {
        return E_POINTER;
    }

    /* Ensure the sockaddr is initialised correctly */
    if ((sockAddr->sin_family != AF_INET) && (sockAddr->sin_family != AF_INET6))
    {
        return E_FAIL;
    }

    memcpy(pSockAddr, &impl->sockAddr, sizeof(SOCKADDR_STORAGE));
    return S_OK;
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetExclusive(IWSDUdpAddress *This, BOOL fExclusive)
{
    FIXME("(%p, %d)\n", This, fExclusive);
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetExclusive(IWSDUdpAddress *This)
{
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetMessageType(IWSDUdpAddress *This, WSDUdpMessageType messageType)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);

    TRACE("(%p, %d)\n", This, messageType);

    impl->messageType = messageType;
    return S_OK;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetMessageType(IWSDUdpAddress *This, WSDUdpMessageType *pMessageType)
{
    IWSDUdpAddressImpl *impl = impl_from_IWSDUdpAddress(This);

    TRACE("(%p, %p)\n", This, pMessageType);

    if (pMessageType == NULL)
    {
        return E_POINTER;
    }

    *pMessageType = impl->messageType;
    return S_OK;
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetTTL(IWSDUdpAddress *This, DWORD dwTTL)
{
    FIXME("(%p, %d)\n", This, dwTTL);
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetTTL(IWSDUdpAddress *This, DWORD *pdwTTL)
{
    FIXME("(%p, %p)\n", This, pdwTTL);
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_SetAlias(IWSDUdpAddress *This, const GUID *pAlias)
{
    FIXME("(%p, %s)\n", This, debugstr_guid(pAlias));
    return E_NOTIMPL;
}

static HRESULT WINAPI IWSDUdpAddressImpl_GetAlias(IWSDUdpAddress *This, GUID *pAlias)
{
    FIXME("(%p, %p)\n", This, pAlias);
    return E_NOTIMPL;
}

static const IWSDUdpAddressVtbl udpAddressVtbl =
{
    IWSDUdpAddressImpl_QueryInterface,
    IWSDUdpAddressImpl_AddRef,
    IWSDUdpAddressImpl_Release,
    IWSDUdpAddressImpl_Serialize,
    IWSDUdpAddressImpl_Deserialize,
    IWSDUdpAddressImpl_GetPort,
    IWSDUdpAddressImpl_SetPort,
    IWSDUdpAddressImpl_GetTransportAddress,
    IWSDUdpAddressImpl_GetTransportAddressEx,
    IWSDUdpAddressImpl_SetTransportAddress,
    IWSDUdpAddressImpl_SetSockaddr,
    IWSDUdpAddressImpl_GetSockaddr,
    IWSDUdpAddressImpl_SetExclusive,
    IWSDUdpAddressImpl_GetExclusive,
    IWSDUdpAddressImpl_SetMessageType,
    IWSDUdpAddressImpl_GetMessageType,
    IWSDUdpAddressImpl_SetTTL,
    IWSDUdpAddressImpl_GetTTL,
    IWSDUdpAddressImpl_SetAlias,
    IWSDUdpAddressImpl_GetAlias
};

HRESULT WINAPI WSDCreateUdpAddress(IWSDUdpAddress **ppAddress)
{
    IWSDUdpAddressImpl *obj;

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

    if (ppAddress == NULL)
    {
        WARN("Invalid parameter: ppAddress == NULL\n");
        return E_POINTER;
    }

    *ppAddress = NULL;

    obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*obj));

    if (!obj)
    {
        WARN("Out of memory\n");
        return E_OUTOFMEMORY;
    }

    obj->IWSDUdpAddress_iface.lpVtbl = &udpAddressVtbl;
    obj->ref = 1;

    *ppAddress = &obj->IWSDUdpAddress_iface;
    TRACE("Returning iface %p\n", *ppAddress);

    return S_OK;
}
