/*
 * POP3 Transport
 *
 * Copyright 2008 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
 */

#define COBJMACROS
#define NONAMELESSUNION

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

#include "windef.h"
#include "winbase.h"
#include "winnt.h"
#include "winuser.h"
#include "objbase.h"
#include "mimeole.h"
#include "wine/debug.h"

#include "inetcomm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);

enum parse_state
{
    STATE_NONE,
    STATE_OK,
    STATE_MULTILINE,
    STATE_DONE
};

typedef struct
{
    InternetTransport InetTransport;
    ULONG refs;
    POP3COMMAND command;
    POP3CMDTYPE type;
    char *response;
    char *ptr;
    enum parse_state state;
    BOOL valid_info;
    DWORD msgid;
    DWORD preview_lines;
} POP3Transport;

static HRESULT parse_response(POP3Transport *This)
{
    switch (This->state)
    {
    case STATE_NONE:
    {
        if (strlen(This->response) < 3)
        {
            WARN("parse error\n");
            This->state = STATE_DONE;
            return S_FALSE;
        }
        if (!memcmp(This->response, "+OK", 3))
        {
            This->ptr = This->response + 3;
            This->state = STATE_OK;
            return S_OK;
        }
        This->state = STATE_DONE;
        return S_FALSE;
    }
    default: return S_OK;
    }
}

static HRESULT parse_uidl_response(POP3Transport *This, POP3UIDL *uidl)
{
    char *p;

    uidl->dwPopId = 0;
    uidl->pszUidl = NULL;
    switch (This->state)
    {
    case STATE_OK:
    {
        if (This->type == POP3CMD_GET_POPID)
        {
            if ((p = strchr(This->ptr, ' ')))
            {
                while (*p == ' ') p++;
                sscanf(p, "%u", &uidl->dwPopId);
                if ((p = strchr(p, ' ')))
                {
                    while (*p == ' ') p++;
                    uidl->pszUidl = p;
                    This->valid_info = TRUE;
                }
             }
             This->state = STATE_DONE;
             return S_OK;
        }
        This->state = STATE_MULTILINE;
        return S_OK;
    }
    case STATE_MULTILINE:
    {
        if (This->response[0] == '.' && !This->response[1])
        {
            This->valid_info = FALSE;
            This->state = STATE_DONE;
            return S_OK;
        }
        sscanf(This->response, "%u", &uidl->dwPopId);
        if ((p = strchr(This->response, ' ')))
        {
            while (*p == ' ') p++;
            uidl->pszUidl = p;
            This->valid_info = TRUE;
            return S_OK;
        }
    }
    default:
    {
        WARN("parse error\n");
        This->state = STATE_DONE;
        return S_FALSE;
    }
    }
}

static HRESULT parse_stat_response(POP3Transport *This, POP3STAT *stat)
{
    char *p;

    stat->cMessages = 0;
    stat->cbMessages = 0;
    switch (This->state)
    {
    case STATE_OK:
    {
        if ((p = strchr(This->ptr, ' ')))
        {
            while (*p == ' ') p++;
            sscanf(p, "%u %u", &stat->cMessages, &stat->cbMessages);
            This->valid_info = TRUE;
            This->state = STATE_DONE;
            return S_OK;
        }
    }
    default:
    {
        WARN("parse error\n");
        This->state = STATE_DONE;
        return S_FALSE;
    }
    }
}

static HRESULT parse_list_response(POP3Transport *This, POP3LIST *list)
{
    char *p;

    list->dwPopId = 0;
    list->cbSize = 0;
    switch (This->state)
    {
    case STATE_OK:
    {
        if (This->type == POP3CMD_GET_POPID)
        {
            if ((p = strchr(This->ptr, ' ')))
            {
                while (*p == ' ') p++;
                sscanf(p, "%u %u", &list->dwPopId, &list->cbSize);
                This->valid_info = TRUE;
            }
            This->state = STATE_DONE;
            return S_OK;
        }
        This->state = STATE_MULTILINE;
        return S_OK;
    }
    case STATE_MULTILINE:
    {
        if (This->response[0] == '.' && !This->response[1])
        {
            This->valid_info = FALSE;
            This->state = STATE_DONE;
            return S_OK;
        }
        sscanf(This->response, "%u", &list->dwPopId);
        if ((p = strchr(This->response, ' ')))
        {
            while (*p == ' ') p++;
            sscanf(p, "%u", &list->cbSize);
            This->valid_info = TRUE;
            return S_OK;
        }
    }
    default:
    {
        WARN("parse error\n");
        This->state = STATE_DONE;
        return S_FALSE;
    }
    }
}

static HRESULT parse_dele_response(POP3Transport *This, DWORD *dwPopId)
{
    switch (This->state)
    {
    case STATE_OK:
    {
        *dwPopId = 0; /* FIXME */
        This->state = STATE_DONE;
        return S_OK;
    }
    default:
    {
        WARN("parse error\n");
        This->state = STATE_DONE;
        return S_FALSE;
    }
    }
}

static HRESULT parse_retr_response(POP3Transport *This, POP3RETR *retr)
{
    switch (This->state)
    {
    case STATE_OK:
    {
        retr->fHeader = FALSE;
        retr->fBody = FALSE;
        retr->dwPopId = This->msgid;
        retr->cbSoFar = 0;
        retr->pszLines = This->response;
        retr->cbLines = 0;

        This->state = STATE_MULTILINE;
        This->valid_info = FALSE;
        return S_OK;
    }
    case STATE_MULTILINE:
    {
        int len;

        if (This->response[0] == '.' && !This->response[1])
        {
            retr->cbLines = retr->cbSoFar;
            This->state = STATE_DONE;
            return S_OK;
        }
        retr->fHeader = TRUE;
        if (!This->response[0]) retr->fBody = TRUE;

        len = strlen(This->response);
        retr->cbSoFar += len;
        retr->pszLines = This->response;
        retr->cbLines = len;

        This->valid_info = TRUE;
        return S_OK;
    }
    default:
    {
        WARN("parse error\n");
        This->state = STATE_DONE;
        return S_FALSE;
    }
    }
}

static HRESULT parse_top_response(POP3Transport *This, POP3TOP *top)
{
    switch (This->state)
    {
    case STATE_OK:
    {
        top->fHeader = FALSE;
        top->fBody = FALSE;
        top->dwPopId = This->msgid;
        top->cPreviewLines = This->preview_lines;
        top->cbSoFar = 0;
        top->pszLines = This->response;
        top->cbLines = 0;

        This->state = STATE_MULTILINE;
        This->valid_info = FALSE;
        return S_OK;
    }
    case STATE_MULTILINE:
    {
        int len;

        if (This->response[0] == '.' && !This->response[1])
        {
            top->cbLines = top->cbSoFar;
            This->state = STATE_DONE;
            return S_OK;
        }
        top->fHeader = TRUE;
        if (!This->response[0]) top->fBody = TRUE;

        len = strlen(This->response);
        top->cbSoFar += len;
        top->pszLines = This->response;
        top->cbLines = len;

        This->valid_info = TRUE;
        return S_OK;
    }
    default:
    {
        WARN("parse error\n");
        This->state = STATE_DONE;
        return S_FALSE;
    }
    }
}

static void init_parser(POP3Transport *This, POP3COMMAND command, POP3CMDTYPE type)
{
    This->state = STATE_NONE;
    This->command = command;
    This->type = type;
}

static HRESULT POP3Transport_ParseResponse(POP3Transport *This, char *pszResponse, POP3RESPONSE *pResponse)
{
    HRESULT hr;

    TRACE("response: %s\n", debugstr_a(pszResponse));

    This->response = pszResponse;
    This->valid_info = FALSE;
    TRACE("state %u\n", This->state);

    if (SUCCEEDED((hr = parse_response(This))))
    {
        switch (This->command)
        {
        case POP3_UIDL: hr = parse_uidl_response(This, &pResponse->u.rUidlInfo); break;
        case POP3_STAT: hr = parse_stat_response(This, &pResponse->u.rStatInfo); break;
        case POP3_LIST: hr = parse_list_response(This, &pResponse->u.rListInfo); break;
        case POP3_DELE: hr = parse_dele_response(This, &pResponse->u.dwPopId); break;
        case POP3_RETR: hr = parse_retr_response(This, &pResponse->u.rRetrInfo); break;
        case POP3_TOP: hr = parse_top_response(This, &pResponse->u.rTopInfo); break;
        default:
            This->state = STATE_DONE;
            break;
        }
    }
    pResponse->command = This->command;
    pResponse->fDone = (This->state == STATE_DONE);
    pResponse->fValidInfo = This->valid_info;
    pResponse->rIxpResult.hrResult = hr;
    pResponse->rIxpResult.pszResponse = pszResponse;
    pResponse->rIxpResult.uiServerError = 0;
    pResponse->rIxpResult.hrServerError = pResponse->rIxpResult.hrResult;
    pResponse->rIxpResult.dwSocketError = WSAGetLastError();
    pResponse->rIxpResult.pszProblem = NULL;
    pResponse->pTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3;

    if (This->InetTransport.pCallback && This->InetTransport.fCommandLogging)
    {
        ITransportCallback_OnCommand(This->InetTransport.pCallback, CMD_RESP,
            pResponse->rIxpResult.pszResponse, pResponse->rIxpResult.hrServerError,
            (IInternetTransport *)&This->InetTransport.u.vtbl);
    }
    return S_OK;
}

static void POP3Transport_CallbackProcessDELEResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvDELEResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessDELEResp);
}

static void POP3Transport_CallbackProcessNOOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvNOOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessNOOPResp);
}

static void POP3Transport_CallbackProcessRSETResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvRSETResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessRSETResp);
}

static void POP3Transport_CallbackProcessRETRResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);

    if (!response.fDone)
    {
        InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessRETRResp);
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvRETRResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessRETRResp);
}

static void POP3Transport_CallbackProcessTOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);

    if (!response.fDone)
    {
        InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessTOPResp);
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvTOPResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessTOPResp);
}

static void POP3Transport_CallbackProcessLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);

    if (!response.fDone)
    {
        InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessLISTResp);
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessLISTResp);
}

static void POP3Transport_CallbackProcessUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);

    if (!response.fDone)
    {
        InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUIDLResp);
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUIDLResp);
}

static void POP3Transport_CallbackProcessSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessSTATResp);
}

static void POP3Transport_CallbackProcessPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED);
    InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED);

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
}

static void POP3Transport_CallbackRecvPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessPASSResp);
}

static void POP3Transport_CallbackProcessUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    static char pass[] = "PASS ";
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    char *command;
    int len;
    HRESULT hr;

    TRACE("\n");

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);

    len = sizeof(pass) + strlen(This->InetTransport.ServerInfo.szPassword) + 2; /* "\r\n" */
    command = HeapAlloc(GetProcessHeap(), 0, len);

    strcpy(command, pass);
    strcat(command, This->InetTransport.ServerInfo.szPassword);
    strcat(command, "\r\n");

    init_parser(This, POP3_PASS, POP3_NONE);

    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp);
    HeapFree(GetProcessHeap(), 0, command);
}

static void POP3Transport_CallbackRecvUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUSERResp);
}

static void POP3Transport_CallbackSendUSERCmd(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    static char user[] = "USER ";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("\n");

    len = sizeof(user) + strlen(This->InetTransport.ServerInfo.szUserName) + 2; /* "\r\n" */
    command = HeapAlloc(GetProcessHeap(), 0, len);

    strcpy(command, user);
    strcat(command, This->InetTransport.ServerInfo.szUserName);
    strcat(command, "\r\n");
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp);

    HeapFree(GetProcessHeap(), 0, command);
}

static void POP3Transport_CallbackProcessQUITResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;
    POP3RESPONSE response;
    HRESULT hr;

    TRACE("%s\n", debugstr_an(pBuffer, cbBuffer));

    hr = POP3Transport_ParseResponse(This, pBuffer, &response);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }

    IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
    InternetTransport_DropConnection(&This->InetTransport);
}

static void POP3Transport_CallbackRecvQUITResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");
    InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessQUITResponse);
}

static HRESULT WINAPI POP3Transport_QueryInterface(IPOP3Transport *iface, REFIID riid, void **ppv)
{
    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IInternetTransport) ||
        IsEqualIID(riid, &IID_IPOP3Transport))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    *ppv = NULL;
    FIXME("no interface for %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI POP3Transport_AddRef(IPOP3Transport *iface)
{
    POP3Transport *This = (POP3Transport *)iface;
    return InterlockedIncrement((LONG *)&This->refs);
}

static ULONG WINAPI POP3Transport_Release(IPOP3Transport *iface)
{
    POP3Transport *This = (POP3Transport *)iface;
    ULONG refs = InterlockedDecrement((LONG *)&This->refs);
    if (!refs)
    {
        TRACE("destroying %p\n", This);
        if (This->InetTransport.Status != IXP_DISCONNECTED)
            InternetTransport_DropConnection(&This->InetTransport);
        if (This->InetTransport.pCallback) ITransportCallback_Release(This->InetTransport.pCallback);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refs;
}

static HRESULT WINAPI POP3Transport_GetServerInfo(IPOP3Transport *iface,
    LPINETSERVER pInetServer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("(%p)\n", pInetServer);
    return InternetTransport_GetServerInfo(&This->InetTransport, pInetServer);
}

static IXPTYPE WINAPI POP3Transport_GetIXPType(IPOP3Transport *iface)
{
    TRACE("()\n");
    return IXP_POP3;
}

static HRESULT WINAPI POP3Transport_IsState(IPOP3Transport *iface, IXPISSTATE isstate)
{
    FIXME("(%u)\n", isstate);
    return E_NOTIMPL;
}

static HRESULT WINAPI POP3Transport_InetServerFromAccount(
    IPOP3Transport *iface, IImnAccount *pAccount, LPINETSERVER pInetServer)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("(%p, %p)\n", pAccount, pInetServer);
    return InternetTransport_InetServerFromAccount(&This->InetTransport, pAccount, pInetServer);
}

static HRESULT WINAPI POP3Transport_Connect(IPOP3Transport *iface,
    LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging)
{
    POP3Transport *This = (POP3Transport *)iface;
    HRESULT hr;

    TRACE("(%p, %s, %s)\n", pInetServer, fAuthenticate ? "TRUE" : "FALSE", fCommandLogging ? "TRUE" : "FALSE");

    hr = InternetTransport_Connect(&This->InetTransport, pInetServer, fAuthenticate, fCommandLogging);
    if (FAILED(hr))
        return hr;

    init_parser(This, POP3_USER, POP3_NONE);
    return InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackSendUSERCmd);
}

static HRESULT WINAPI POP3Transport_HandsOffCallback(IPOP3Transport *iface)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("()\n");
    return InternetTransport_HandsOffCallback(&This->InetTransport);
}

static HRESULT WINAPI POP3Transport_Disconnect(IPOP3Transport *iface)
{
    TRACE("()\n");
    return IPOP3Transport_CommandQUIT(iface);
}

static HRESULT WINAPI POP3Transport_DropConnection(IPOP3Transport *iface)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("()\n");
    return InternetTransport_DropConnection(&This->InetTransport);
}

static HRESULT WINAPI POP3Transport_GetStatus(IPOP3Transport *iface,
    IXPSTATUS *pCurrentStatus)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("()\n");
    return InternetTransport_GetStatus(&This->InetTransport, pCurrentStatus);
}

static HRESULT WINAPI POP3Transport_InitNew(IPOP3Transport *iface,
    LPSTR pszLogFilePath, IPOP3Callback *pCallback)
{
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath), pCallback);

    if (!pCallback)
        return E_INVALIDARG;

    if (pszLogFilePath)
        FIXME("not using log file of %s, use Wine debug logging instead\n",
            debugstr_a(pszLogFilePath));

    IPOP3Callback_AddRef(pCallback);
    This->InetTransport.pCallback = (ITransportCallback *)pCallback;
    This->InetTransport.fInitialised = TRUE;

    return S_OK;
}

static HRESULT WINAPI POP3Transport_MarkItem(IPOP3Transport *iface, POP3MARKTYPE marktype,
    DWORD dwPopId, boolean fMarked)
{
    FIXME("(%u, %u, %d)\n", marktype, dwPopId, fMarked);
    return E_NOTIMPL;
}

static HRESULT WINAPI POP3Transport_CommandAUTH(IPOP3Transport *iface, LPSTR pszAuthType)
{
    FIXME("(%s)\n", pszAuthType);
    return E_NOTIMPL;
}

static HRESULT WINAPI POP3Transport_CommandUSER(IPOP3Transport *iface, LPSTR username)
{
    static char user[] = "USER ";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("(%s)\n", username);

    len = sizeof(user) + strlen(username) + 2; /* "\r\n" */
    if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;

    strcpy(command, user);
    strcat(command, username);
    strcat(command, "\r\n");

    init_parser(This, POP3_USER, POP3_NONE);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp);

    HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandPASS(IPOP3Transport *iface, LPSTR password)
{
    static char pass[] = "PASS ";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

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

    len = sizeof(pass) + strlen(password) + 2; /* "\r\n" */
    if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;

    strcpy(command, pass);
    strcat(command, password);
    strcat(command, "\r\n");

    init_parser(This, POP3_PASS, POP3_NONE);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp);

    HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandLIST(
    IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
{
    static char list[] = "LIST %u\r\n";
    static char list_all[] = "LIST\r\n";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("(%u, %u)\n", cmdtype, dwPopId);

    if (dwPopId)
    {
        len = sizeof(list) + 10 + 2; /* "4294967296" + "\r\n" */
        if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;
        sprintf(command, list, dwPopId);
    }
    else command = list_all;

    init_parser(This, POP3_LIST, cmdtype);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvLISTResp);

    if (dwPopId) HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandTOP(
    IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId, DWORD cPreviewLines)
{
    static char top[] = "TOP %u %u\r\n";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("(%u, %u, %u)\n", cmdtype, dwPopId, cPreviewLines);

    len = sizeof(top) + 20 + 2; /* 2 * "4294967296" + "\r\n" */
    if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;
    sprintf(command, top, dwPopId, cPreviewLines);

    This->preview_lines = cPreviewLines;
    init_parser(This, POP3_TOP, cmdtype);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvTOPResp);

    HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandQUIT(IPOP3Transport *iface)
{
    static char command[] = "QUIT\r\n";
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("()\n");

    InternetTransport_ChangeStatus(&This->InetTransport, IXP_DISCONNECTING);

    init_parser(This, POP3_QUIT, POP3_NONE);
    return InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvQUITResp);
}

static HRESULT WINAPI POP3Transport_CommandSTAT(IPOP3Transport *iface)
{
    static char stat[] = "STAT\r\n";
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");

    init_parser(This, POP3_STAT, POP3_NONE);
    InternetTransport_DoCommand(&This->InetTransport, stat, POP3Transport_CallbackRecvSTATResp);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandNOOP(IPOP3Transport *iface)
{
    static char noop[] = "NOOP\r\n";
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");

    init_parser(This, POP3_NOOP, POP3_NONE);
    InternetTransport_DoCommand(&This->InetTransport, noop, POP3Transport_CallbackRecvNOOPResp);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandRSET(IPOP3Transport *iface)
{
    static char rset[] = "RSET\r\n";
    POP3Transport *This = (POP3Transport *)iface;

    TRACE("\n");

    init_parser(This, POP3_RSET, POP3_NONE);
    InternetTransport_DoCommand(&This->InetTransport, rset, POP3Transport_CallbackRecvRSETResp);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandUIDL(
    IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
{
    static char uidl[] = "UIDL %u\r\n";
    static char uidl_all[] = "UIDL\r\n";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("(%u, %u)\n", cmdtype, dwPopId);

    if (dwPopId)
    {
        len = sizeof(uidl) + 10 + 2; /* "4294967296" + "\r\n" */
        if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;
        sprintf(command, uidl, dwPopId);
    }
    else command = uidl_all;

    init_parser(This, POP3_UIDL, cmdtype);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUIDLResp);

    if (dwPopId) HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandDELE(
    IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
{
    static char dele[] = "DELE %u\r\n";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("(%u, %u)\n", cmdtype, dwPopId);

    len = sizeof(dele) + 10 + 2; /* "4294967296" + "\r\n" */
    if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;
    sprintf(command, dele, dwPopId);

    init_parser(This, POP3_DELE, cmdtype);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvDELEResp);

    HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static HRESULT WINAPI POP3Transport_CommandRETR(
    IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
{
    static char retr[] = "RETR %u\r\n";
    POP3Transport *This = (POP3Transport *)iface;
    char *command;
    int len;

    TRACE("(%u, %u)\n", cmdtype, dwPopId);

    len = sizeof(retr) + 10 + 2; /* "4294967296" + "\r\n" */
    if (!(command = HeapAlloc(GetProcessHeap(), 0, len))) return S_FALSE;
    sprintf(command, retr, dwPopId);

    init_parser(This, POP3_RETR, cmdtype);
    InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvRETRResp);

    HeapFree(GetProcessHeap(), 0, command);
    return S_OK;
}

static const IPOP3TransportVtbl POP3TransportVtbl =
{
    POP3Transport_QueryInterface,
    POP3Transport_AddRef,
    POP3Transport_Release,
    POP3Transport_GetServerInfo,
    POP3Transport_GetIXPType,
    POP3Transport_IsState,
    POP3Transport_InetServerFromAccount,
    POP3Transport_Connect,
    POP3Transport_HandsOffCallback,
    POP3Transport_Disconnect,
    POP3Transport_DropConnection,
    POP3Transport_GetStatus,
    POP3Transport_InitNew,
    POP3Transport_MarkItem,
    POP3Transport_CommandAUTH,
    POP3Transport_CommandUSER,
    POP3Transport_CommandPASS,
    POP3Transport_CommandLIST,
    POP3Transport_CommandTOP,
    POP3Transport_CommandQUIT,
    POP3Transport_CommandSTAT,
    POP3Transport_CommandNOOP,
    POP3Transport_CommandRSET,
    POP3Transport_CommandUIDL,
    POP3Transport_CommandDELE,
    POP3Transport_CommandRETR
};

HRESULT WINAPI CreatePOP3Transport(IPOP3Transport **ppTransport)
{
    HRESULT hr;
    POP3Transport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->InetTransport.u.vtblPOP3 = &POP3TransportVtbl;
    This->refs = 0;
    hr = InternetTransport_Init(&This->InetTransport);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, This);
        return hr;
    }

    *ppTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3;
    IPOP3Transport_AddRef(*ppTransport);

    return S_OK;
}

static HRESULT WINAPI POP3TransportCF_QueryInterface(LPCLASSFACTORY iface,
    REFIID riid, LPVOID *ppv)
{
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
    {
        *ppv = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    return E_NOINTERFACE;
}

static ULONG WINAPI POP3TransportCF_AddRef(LPCLASSFACTORY iface)
{
    return 2; /* non-heap based object */
}

static ULONG WINAPI POP3TransportCF_Release(LPCLASSFACTORY iface)
{
    return 1; /* non-heap based object */
}

static HRESULT WINAPI POP3TransportCF_CreateInstance(LPCLASSFACTORY iface,
    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
    HRESULT hr;
    IPOP3Transport *pPop3Transport;

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

    *ppv = NULL;

    if (pUnk)
        return CLASS_E_NOAGGREGATION;

    hr = CreatePOP3Transport(&pPop3Transport);
    if (FAILED(hr))
        return hr;

    hr = IPOP3Transport_QueryInterface(pPop3Transport, riid, ppv);
    IPOP3Transport_Release(pPop3Transport);

    return hr;
}

static HRESULT WINAPI POP3TransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
{
    FIXME("(%d)\n",fLock);
    return S_OK;
}

static const IClassFactoryVtbl POP3TransportCFVtbl =
{
    POP3TransportCF_QueryInterface,
    POP3TransportCF_AddRef,
    POP3TransportCF_Release,
    POP3TransportCF_CreateInstance,
    POP3TransportCF_LockServer
};
static const IClassFactoryVtbl *POP3TransportCF = &POP3TransportCFVtbl;

HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv)
{
    return IClassFactory_QueryInterface((IClassFactory *)&POP3TransportCF, riid, ppv);
}
