/*
 * 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 "winuser.h"
#include "winsock2.h"
#include "ws2tcpip.h"
#include "objbase.h"
#include "ole2.h"
#include "mimeole.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;

    *pInetServer = This->ServerInfo;
    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;

    This->ServerInfo = *pInetServer;
    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)
        {
            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);
        }
        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();
}
