/*
 * Internet Messaging Transport Base Class
 *
 * Copyright 2006 Robert Shearman 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
 */

#define COBJMACROS

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

#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winsock2.h"
#include "ws2tcpip.h"

#include "wine/debug.h"

#include "inetcomm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);

static const WCHAR wszClassName[] = {'T','h','o','r','C','o','n','n','W','n','d','C','l','a','s','s',0};

#define IX_READ     (WM_USER + 0)
#define IX_READLINE (WM_USER + 1)
#define IX_WRITE    (WM_USER + 2)

HRESULT InternetTransport_Init(InternetTransport *This)
{
    This->pCallback = NULL;
    This->Status = IXP_DISCONNECTED;
    This->Socket = -1;
    This->fCommandLogging = FALSE;
    This->fnCompletion = NULL;

    return S_OK;
}

HRESULT InternetTransport_GetServerInfo(InternetTransport *This, LPINETSERVER pInetServer)
{
    if (This->Status == IXP_DISCONNECTED)
        return IXP_E_NOT_CONNECTED;

    memcpy(pInetServer, &This->ServerInfo, sizeof(*pInetServer));
    return S_OK;
}

HRESULT InternetTransport_InetServerFromAccount(InternetTransport *This,
    IImnAccount *pAccount, LPINETSERVER pInetServer)
{
    FIXME("(%p, %p): stub\n", pAccount, pInetServer);
    return E_NOTIMPL;
}

HRESULT InternetTransport_Connect(InternetTransport *This,
    LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging)
{
    struct addrinfo *ai;
    struct addrinfo *ai_cur;
    struct addrinfo hints;
    int ret;
    char szPort[10];

    if (This->Status != IXP_DISCONNECTED)
        return IXP_E_ALREADY_CONNECTED;

    memcpy(&This->ServerInfo, pInetServer, sizeof(This->ServerInfo));
    This->fCommandLogging = fCommandLogging;

    This->hwnd = CreateWindowW(wszClassName, wszClassName, 0, 0, 0, 0, 0, NULL, NULL, NULL, 0);
    if (!This->hwnd)
        return HRESULT_FROM_WIN32(GetLastError());
    SetWindowLongPtrW(This->hwnd, GWLP_USERDATA, (LONG_PTR)This);

    hints.ai_flags          = 0;
    hints.ai_family         = PF_UNSPEC;
    hints.ai_socktype       = SOCK_STREAM;
    hints.ai_protocol       = IPPROTO_TCP;
    hints.ai_addrlen        = 0;
    hints.ai_addr           = NULL;
    hints.ai_canonname      = NULL;
    hints.ai_next           = NULL;

    snprintf(szPort, sizeof(szPort), "%d", (unsigned short)pInetServer->dwPort);

    InternetTransport_ChangeStatus(This, IXP_FINDINGHOST);

    ret = getaddrinfo(pInetServer->szServerName, szPort, &hints, &ai);
    if (ret)
    {
        ERR("getaddrinfo failed: %d\n", ret);
        return IXP_E_CANT_FIND_HOST;
    }

    for (ai_cur = ai; ai_cur; ai_cur = ai->ai_next)
    {
        int so;

        if (TRACE_ON(inetcomm))
        {
            char host[256];
            char service[256];
            getnameinfo(ai_cur->ai_addr, ai_cur->ai_addrlen,
                host, sizeof(host), service, sizeof(service),
                NI_NUMERICHOST | NI_NUMERICSERV);
            TRACE("trying %s:%s\n", host, service);
        }

        InternetTransport_ChangeStatus(This, IXP_CONNECTING);

        so = socket(ai_cur->ai_family, ai_cur->ai_socktype, ai_cur->ai_protocol);
        if (so == -1)
        {
            WARN("socket() failed\n");
            continue;
        }
        This->Socket = so;

        /* FIXME: set to async */

        if (0 > connect(This->Socket, ai_cur->ai_addr, ai_cur->ai_addrlen))
        {
            WARN("connect() failed\n");
            closesocket(This->Socket);
            continue;
        }
        InternetTransport_ChangeStatus(This, IXP_CONNECTED);

        /* FIXME: call WSAAsyncSelect */

        freeaddrinfo(ai);
        TRACE("connected\n");
        return S_OK;
    }

    freeaddrinfo(ai);

    return IXP_E_CANT_FIND_HOST;
}

HRESULT InternetTransport_HandsOffCallback(InternetTransport *This)
{
    if (!This->pCallback)
        return S_FALSE;

    ITransportCallback_Release(This->pCallback);
    This->pCallback = NULL;

    return S_OK;
}

HRESULT InternetTransport_DropConnection(InternetTransport *This)
{
    int ret;

    if (This->Status == IXP_DISCONNECTED)
        return IXP_E_NOT_CONNECTED;

    ret = shutdown(This->Socket, SD_BOTH);

    ret = closesocket(This->Socket);

    DestroyWindow(This->hwnd);
    This->hwnd = NULL;

    InternetTransport_ChangeStatus(This, IXP_DISCONNECTED);

    return S_OK;
}

HRESULT InternetTransport_GetStatus(InternetTransport *This,
    IXPSTATUS *pCurrentStatus)
{
    *pCurrentStatus = This->Status;
    return S_OK;
}

HRESULT InternetTransport_ChangeStatus(InternetTransport *This, IXPSTATUS Status)
{
    This->Status = Status;
    if (This->pCallback)
        ITransportCallback_OnStatus(This->pCallback, Status,
            (IInternetTransport *)&This->u.vtbl);
    return S_OK;
}

HRESULT InternetTransport_Read(InternetTransport *This, int cbBuffer,
    INETXPORT_COMPLETION_FUNCTION fnCompletion)
{
    if (This->Status == IXP_DISCONNECTED)
        return IXP_E_NOT_CONNECTED;

    if (This->fnCompletion)
        return IXP_E_BUSY;

    This->fnCompletion = fnCompletion;

    This->cbBuffer = cbBuffer;
    This->pBuffer = HeapAlloc(GetProcessHeap(), 0, This->cbBuffer);
    This->iCurrentBufferOffset = 0;

    if (WSAAsyncSelect(This->Socket, This->hwnd, IX_READ, FD_READ) == SOCKET_ERROR)
    {
        ERR("WSAAsyncSelect failed with error %d\n", WSAGetLastError());
        /* FIXME: handle error */
    }
    return S_OK;
}

HRESULT InternetTransport_ReadLine(InternetTransport *This,
    INETXPORT_COMPLETION_FUNCTION fnCompletion)
{
    if (This->Status == IXP_DISCONNECTED)
        return IXP_E_NOT_CONNECTED;

    if (This->fnCompletion)
        return IXP_E_BUSY;

    This->fnCompletion = fnCompletion;

    This->cbBuffer = 1024;
    This->pBuffer = HeapAlloc(GetProcessHeap(), 0, This->cbBuffer);
    This->iCurrentBufferOffset = 0;

    if (WSAAsyncSelect(This->Socket, This->hwnd, IX_READLINE, FD_READ) == SOCKET_ERROR)
    {
        ERR("WSAAsyncSelect failed with error %d\n", WSAGetLastError());
        /* FIXME: handle error */
    }
    return S_OK;
}

HRESULT InternetTransport_Write(InternetTransport *This, const char *pvData,
    int cbSize, INETXPORT_COMPLETION_FUNCTION fnCompletion)
{
    int ret;

    if (This->Status == IXP_DISCONNECTED)
        return IXP_E_NOT_CONNECTED;

    if (This->fnCompletion)
        return IXP_E_BUSY;

    /* FIXME: do this asynchronously */
    ret = send(This->Socket, pvData, cbSize, 0);
    if (ret == SOCKET_ERROR)
    {
        ERR("send failed with error %d\n", WSAGetLastError());
        /* FIXME: handle error */
    }

    fnCompletion((IInternetTransport *)&This->u.vtbl, NULL, 0);

    return S_OK;
}

static LRESULT CALLBACK InternetTransport_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == IX_READ)
    {
        InternetTransport *This = (InternetTransport *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);

        /* no work to do */
        if (!This->fnCompletion)
            return 0;

        while (This->iCurrentBufferOffset < This->cbBuffer)
        {
            if (recv(This->Socket, &This->pBuffer[This->iCurrentBufferOffset], 1, 0) <= 0)
            {
                if (WSAGetLastError() == WSAEWOULDBLOCK)
                    break;

                ERR("recv failed with error %d\n", WSAGetLastError());
                /* FIXME: handle error */
            }

            This->iCurrentBufferOffset++;
        }
        if (This->iCurrentBufferOffset == This->cbBuffer)
        {
            INETXPORT_COMPLETION_FUNCTION fnCompletion = This->fnCompletion;
            char *pBuffer;

            This->fnCompletion = NULL;
            pBuffer = This->pBuffer;
            This->pBuffer = NULL;
            fnCompletion((IInternetTransport *)&This->u.vtbl, pBuffer,
                This->iCurrentBufferOffset);
            HeapFree(GetProcessHeap(), 0, pBuffer);
            return 0;
        }

        if (WSAAsyncSelect(This->Socket, hwnd, uMsg, FD_READ) == SOCKET_ERROR)
        {
            ERR("WSAAsyncSelect failed with error %d\n", WSAGetLastError());
            /* FIXME: handle error */
        }
        return 0;
    }
    else if (uMsg == IX_READLINE)
    {
        InternetTransport *This = (InternetTransport *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);

        /* no work to do */
        if (!This->fnCompletion)
            return 0;

        while (This->iCurrentBufferOffset < This->cbBuffer - 1)
        {
            struct timeval tv;
            fd_set infd;

            if (recv(This->Socket, &This->pBuffer[This->iCurrentBufferOffset], 1, 0) <= 0)
            {
                if (WSAGetLastError() == WSAEWOULDBLOCK)
                    break;

                ERR("recv failed with error %d\n", WSAGetLastError());
                /* FIXME: handle error */
                return 0;
            }

            if (This->pBuffer[This->iCurrentBufferOffset] == '\n')
            {
                INETXPORT_COMPLETION_FUNCTION fnCompletion = This->fnCompletion;
                char *pBuffer;

                This->fnCompletion = NULL;
                This->pBuffer[This->iCurrentBufferOffset++] = '\0';
                pBuffer = This->pBuffer;
                This->pBuffer = NULL;

                fnCompletion((IInternetTransport *)&This->u.vtbl, pBuffer,
                    This->iCurrentBufferOffset);

                HeapFree(GetProcessHeap(), 0, pBuffer);
                return 0;
            }
            if (This->pBuffer[This->iCurrentBufferOffset] != '\r')
                This->iCurrentBufferOffset++;

            FD_ZERO(&infd);
            FD_SET(This->Socket, &infd);
            tv.tv_sec = 0;
            tv.tv_usec = 0;
        }
        if (This->iCurrentBufferOffset == This->cbBuffer - 1)
            return 0;

        if (WSAAsyncSelect(This->Socket, hwnd, uMsg, FD_READ) == SOCKET_ERROR)
        {
            ERR("WSAAsyncSelect failed with error %d\n", WSAGetLastError());
            /* FIXME: handle error */
        }
        return 0;
    }
    else
        return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}

BOOL InternetTransport_RegisterClass(HINSTANCE hInstance)
{
    WNDCLASSW cls;
    WSADATA wsadata;

    if (WSAStartup(MAKEWORD(2, 2), &wsadata))
        return FALSE;

    memset(&cls, 0, sizeof(cls));
    cls.hInstance     = hInstance;
    cls.lpfnWndProc   = InternetTransport_WndProc;
    cls.lpszClassName = wszClassName;

    return RegisterClassW(&cls);
}

void InternetTransport_UnregisterClass(HINSTANCE hInstance)
{
    UnregisterClassW(wszClassName, hInstance);
    WSACleanup();
}
