/*
 * 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 "ws2tcpip.h"
#include "windef.h"
#include "winnt.h"
#include "objbase.h"
#include "ole2.h"
#include "mimeole.h"

#include <stdio.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_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;
}

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

    if (This->fnCompletion)
        return IXP_E_BUSY;

    if (This->pCallback && This->fCommandLogging)
    {
        ITransportCallback_OnCommand(This->pCallback, CMD_SEND, (LPSTR)pszCommand, 0,
            (IInternetTransport *)&This->u.vtbl);
    }
    return InternetTransport_Write(This, pszCommand, strlen(pszCommand), fnCompletion);
}

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();
}
