/*
 * SMTP Transport
 *
 * Copyright 2006 Robert Shearman for CodeWeavers
 * 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

#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);

typedef struct
{
    InternetTransport InetTransport;
    ULONG refs;
    BOOL fESMTP;
    SMTPMESSAGE pending_message;
    INETADDR *addrlist;
    ULONG ulCurrentAddressIndex;
} SMTPTransport;

static HRESULT SMTPTransport_ParseResponse(SMTPTransport *This, char *pszResponse, SMTPRESPONSE *pResponse)
{
    HRESULT hrServerError;

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

    if (!isdigit(*pszResponse))
        return IXP_E_SMTP_RESPONSE_ERROR;
    pResponse->pTransport = (ISMTPTransport *)&This->InetTransport.u.vtblSMTP2;
    pResponse->rIxpResult.pszResponse = pszResponse;
    pResponse->rIxpResult.dwSocketError = 0;
    pResponse->rIxpResult.uiServerError = strtol(pszResponse, &pszResponse, 10);
    if (*pszResponse == '-')
    {
        pResponse->fDone = FALSE;
        pszResponse++;
    }
    else
        pResponse->fDone = TRUE;

    switch (pResponse->rIxpResult.uiServerError)
    {
    case 211: hrServerError = IXP_E_SMTP_211_SYSTEM_STATUS; break;
    case 214: hrServerError = IXP_E_SMTP_214_HELP_MESSAGE; break;
    case 220: hrServerError = IXP_E_SMTP_220_READY; break;
    case 221: hrServerError = IXP_E_SMTP_221_CLOSING; break;
    case 245: hrServerError = IXP_E_SMTP_245_AUTH_SUCCESS; break;
    case 250: hrServerError = IXP_E_SMTP_250_MAIL_ACTION_OKAY; break;
    case 251: hrServerError = IXP_E_SMTP_251_FORWARDING_MAIL; break;
    case 334: hrServerError = IXP_E_SMTP_334_AUTH_READY_RESPONSE; break;
    case 354: hrServerError = IXP_E_SMTP_354_START_MAIL_INPUT; break;
    case 421: hrServerError = IXP_E_SMTP_421_NOT_AVAILABLE; break;
    case 450: hrServerError = IXP_E_SMTP_450_MAILBOX_BUSY; break;
    case 451: hrServerError = IXP_E_SMTP_451_ERROR_PROCESSING; break;
    case 452: hrServerError = IXP_E_SMTP_452_NO_SYSTEM_STORAGE; break;
    case 454: hrServerError = IXP_E_SMTP_454_STARTTLS_FAILED; break;
    case 500: hrServerError = IXP_E_SMTP_500_SYNTAX_ERROR; break;
    case 501: hrServerError = IXP_E_SMTP_501_PARAM_SYNTAX; break;
    case 502: hrServerError = IXP_E_SMTP_502_COMMAND_NOTIMPL; break;
    case 503: hrServerError = IXP_E_SMTP_503_COMMAND_SEQ; break;
    case 504: hrServerError = IXP_E_SMTP_504_COMMAND_PARAM_NOTIMPL; break;
    case 530: hrServerError = IXP_E_SMTP_530_STARTTLS_REQUIRED; break;
    case 550: hrServerError = IXP_E_SMTP_550_MAILBOX_NOT_FOUND; break;
    case 551: hrServerError = IXP_E_SMTP_551_USER_NOT_LOCAL; break;
    case 552: hrServerError = IXP_E_SMTP_552_STORAGE_OVERFLOW; break;
    case 553: hrServerError = IXP_E_SMTP_553_MAILBOX_NAME_SYNTAX; break;
    case 554: hrServerError = IXP_E_SMTP_554_TRANSACT_FAILED; break;
    default:
        hrServerError = IXP_E_SMTP_RESPONSE_ERROR;
        break;
    }
    pResponse->rIxpResult.hrResult = hrServerError;
    pResponse->rIxpResult.hrServerError = hrServerError;

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

static void SMTPTransport_CallbackDoNothing(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    TRACE("\n");
}

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

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

static void SMTPTransport_CallbackProcessDATAResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response = { 0 };
    HRESULT hr;

    TRACE("\n");

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

    response.command = SMTP_DATA;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }
}

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

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

static void SMTPTransport_CallbackProcessMAILResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response = { 0 };
    HRESULT hr;

    TRACE("\n");

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

    response.command = SMTP_MAIL;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }
}

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

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

static void SMTPTransport_CallbackProcessRCPTResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response = { 0 };
    HRESULT hr;

    TRACE("\n");

    HeapFree(GetProcessHeap(), 0, This->addrlist);
    This->addrlist = NULL;

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

    response.command = SMTP_RCPT;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }
}

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

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

static void SMTPTransport_CallbackProcessHelloResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response = { 0 };
    HRESULT hr;

    TRACE("\n");

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

    response.command = This->fESMTP ? SMTP_EHLO : SMTP_HELO;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }

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

    /* FIXME: try to authorize */

    /* always changed to this status, even if authorization not support on server */
    InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED);
    InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED);

    memset(&response, 0, sizeof(response));
    response.command = SMTP_CONNECTED;
    response.fDone = TRUE;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);
}

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

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

static void SMTPTransport_CallbackSendHello(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response = { 0 };
    HRESULT hr;
    const char *pszHello;
    char *pszCommand;
    const char szHostName[] = "localhost"; /* FIXME */

    TRACE("\n");

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

    response.command = SMTP_BANNER;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }

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

    This->fESMTP = strstr(response.rIxpResult.pszResponse, "ESMTP") &&
        This->InetTransport.ServerInfo.dwFlags & (ISF_SSLONSAMEPORT|ISF_QUERYDSNSUPPORT|ISF_QUERYAUTHSUPPORT);

    if (This->fESMTP)
        pszHello = "EHLO ";
    else
        pszHello = "HELO ";

    pszCommand = HeapAlloc(GetProcessHeap(), 0, strlen(pszHello) + strlen(szHostName) + 2);
    strcpy(pszCommand, pszHello);
    strcat(pszCommand, szHostName);
    pszCommand[strlen(pszCommand)+1] = '\0';
    pszCommand[strlen(pszCommand)] = '\n';

    InternetTransport_DoCommand(&This->InetTransport, pszCommand,
        SMTPTransport_CallbackRecvHelloResp);

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

static void SMTPTransport_CallbackDisconnect(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response;
    HRESULT hr;

    TRACE("\n");

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

        if (FAILED(response.rIxpResult.hrServerError))
        {
            ERR("server error: %s\n", debugstr_a(pBuffer));
            /* FIXME: handle error */
            return;
        }
    }
    InternetTransport_DropConnection(&This->InetTransport);
}

static void SMTPTransport_CallbackMessageProcessResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response = { 0 };
    HRESULT hr;

    TRACE("\n");

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

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }

    response.command = SMTP_SEND_MESSAGE;
    response.rIxpResult.hrResult = S_OK;
    ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);
}

static void SMTPTransport_CallbackMessageReadResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackMessageProcessResponse);
}

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

    IStream_Release(This->pending_message.pstmMsg);
    InternetTransport_DoCommand(&This->InetTransport, "\n.\n",
        SMTPTransport_CallbackMessageReadResponse);
}

static void SMTPTransport_CallbackMessageSendDataStream(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response;
    HRESULT hr;
    char *pszBuffer;
    ULONG cbSize;

    TRACE("\n");

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

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }

    pszBuffer = HeapAlloc(GetProcessHeap(), 0, This->pending_message.cbSize);
    hr = IStream_Read(This->pending_message.pstmMsg, pszBuffer, This->pending_message.cbSize, NULL);
    if (FAILED(hr))
    {
        /* FIXME: handle error */
        return;
    }
    cbSize = This->pending_message.cbSize;

    /* FIXME: map "\n.\n" to "\n..\n", reallocate memory, update cbSize */

    /* FIXME: properly stream the message rather than writing it all at once */

    hr = InternetTransport_Write(&This->InetTransport, pszBuffer, cbSize,
        SMTPTransport_CallbackMessageSendDOT);

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

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

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

static void SMTPTransport_CallbackMessageSendTo(IInternetTransport *iface, char *pBuffer, int cbBuffer);

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

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

static void SMTPTransport_CallbackMessageSendTo(IInternetTransport *iface, char *pBuffer, int cbBuffer)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    SMTPRESPONSE response;
    HRESULT hr;

    TRACE("\n");

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

    if (FAILED(response.rIxpResult.hrServerError))
    {
        ERR("server error: %s\n", debugstr_a(pBuffer));
        /* FIXME: handle error */
        return;
    }

    for (; This->ulCurrentAddressIndex < This->pending_message.rAddressList.cAddress; This->ulCurrentAddressIndex++)
    {
        TRACE("address[%d]: %s\n", This->ulCurrentAddressIndex,
            This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].szEmail);

        if ((This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].addrtype & ADDR_TOFROM_MASK) == ADDR_TO)
        {
            const char szCommandFormat[] = "RCPT TO: <%s>\n";
            char *szCommand;
            int len = sizeof(szCommandFormat) - 2 /* "%s" */ +
                strlen(This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].szEmail);

            szCommand = HeapAlloc(GetProcessHeap(), 0, len);
            if (!szCommand)
                return;

            sprintf(szCommand, szCommandFormat,
                This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].szEmail);

            This->ulCurrentAddressIndex++;
            hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
                SMTPTransport_CallbackMessageReadToResponse);

            HeapFree(GetProcessHeap(), 0, szCommand);
            return;
        }
    }

    hr = InternetTransport_DoCommand(&This->InetTransport, "DATA\n",
        SMTPTransport_CallbackMessageReadDataResponse);
}

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

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

static HRESULT WINAPI SMTPTransport_QueryInterface(ISMTPTransport2 *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_ISMTPTransport) ||
        IsEqualIID(riid, &IID_ISMTPTransport2))
    {
        *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 SMTPTransport_AddRef(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    return InterlockedIncrement((LONG *)&This->refs);
}

static ULONG WINAPI SMTPTransport_Release(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)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->addrlist);
        HeapFree(GetProcessHeap(), 0, This);
    }
    return refs;
}

static HRESULT WINAPI SMTPTransport_GetServerInfo(ISMTPTransport2 *iface,
    LPINETSERVER pInetServer)
{
    SMTPTransport *This = (SMTPTransport *)iface;

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

static IXPTYPE WINAPI SMTPTransport_GetIXPType(ISMTPTransport2 *iface)
{
    TRACE("()\n");
    return IXP_SMTP;
}

static HRESULT WINAPI SMTPTransport_IsState(ISMTPTransport2 *iface,
    IXPISSTATE isstate)
{
    FIXME("(%d): stub\n", isstate);
    return E_NOTIMPL;
}

static HRESULT WINAPI SMTPTransport_InetServerFromAccount(
    ISMTPTransport2 *iface, IImnAccount *pAccount, LPINETSERVER pInetServer)
{
    SMTPTransport *This = (SMTPTransport *)iface;

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

static HRESULT WINAPI SMTPTransport_Connect(ISMTPTransport2 *iface,
    LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging)
{
    SMTPTransport *This = (SMTPTransport *)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;

    /* this starts the state machine, which continues in SMTPTransport_CallbackSendHELO */
    return InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackSendHello);
}

static HRESULT WINAPI SMTPTransport_HandsOffCallback(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;

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

static HRESULT WINAPI SMTPTransport_Disconnect(ISMTPTransport2 *iface)
{
    TRACE("()\n");
    return ISMTPTransport2_CommandQUIT(iface);
}

static HRESULT WINAPI SMTPTransport_DropConnection(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;

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

static HRESULT WINAPI SMTPTransport_GetStatus(ISMTPTransport2 *iface,
    IXPSTATUS *pCurrentStatus)
{
    SMTPTransport *This = (SMTPTransport *)iface;

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

static HRESULT WINAPI SMTPTransport_InitNew(ISMTPTransport2 *iface,
    LPSTR pszLogFilePath, ISMTPCallback *pCallback)
{
    SMTPTransport *This = (SMTPTransport *)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));

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

    return S_OK;
}

static HRESULT WINAPI SMTPTransport_SendMessage(ISMTPTransport2 *iface,
    LPSMTPMESSAGE pMessage)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    ULONG i, size;
    LPSTR pszFromAddress = NULL;
    const char szCommandFormat[] = "MAIL FROM: <%s>\n";
    char *szCommand;
    int len;
    HRESULT hr;

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

    This->pending_message = *pMessage;
    IStream_AddRef(pMessage->pstmMsg);

    size = pMessage->rAddressList.cAddress * sizeof(INETADDR);
    This->addrlist = HeapAlloc(GetProcessHeap(), 0, size);
    if (!This->addrlist)
        return E_OUTOFMEMORY;

    memcpy(This->addrlist, pMessage->rAddressList.prgAddress, size);
    This->pending_message.rAddressList.prgAddress = This->addrlist;
    This->ulCurrentAddressIndex = 0;

    for (i = 0; i < pMessage->rAddressList.cAddress; i++)
    {
        if ((pMessage->rAddressList.prgAddress[i].addrtype & ADDR_TOFROM_MASK) == ADDR_FROM)
        {
            TRACE("address[%d]: ADDR_FROM, %s\n", i,
                pMessage->rAddressList.prgAddress[i].szEmail);
            pszFromAddress = pMessage->rAddressList.prgAddress[i].szEmail;
        }
        else if ((pMessage->rAddressList.prgAddress[i].addrtype & ADDR_TOFROM_MASK) == ADDR_TO)
        {
            TRACE("address[%d]: ADDR_TO, %s\n", i,
                pMessage->rAddressList.prgAddress[i].szEmail);
        }
    }

    if (!pszFromAddress)
    {
        SMTPRESPONSE response;
        memset(&response, 0, sizeof(response));
        response.command = SMTP_SEND_MESSAGE;
        response.fDone = TRUE;
        response.pTransport = (ISMTPTransport *)&This->InetTransport.u.vtblSMTP2;
        response.rIxpResult.hrResult = IXP_E_SMTP_NO_SENDER;
        ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response);
        return S_OK;
    }
    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszFromAddress);

    szCommand = HeapAlloc(GetProcessHeap(), 0, len);
    if (!szCommand)
        return E_OUTOFMEMORY;

    sprintf(szCommand, szCommandFormat, pszFromAddress);

    hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
        SMTPTransport_CallbackMessageReadFromResponse);

    return hr;
}

static HRESULT WINAPI SMTPTransport_CommandMAIL(ISMTPTransport2 *iface, LPSTR pszEmailFrom)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    const char szCommandFormat[] = "MAIL FROM: <%s>\n";
    char *szCommand;
    int len;
    HRESULT hr;

    TRACE("(%s)\n", debugstr_a(pszEmailFrom));

    if (!pszEmailFrom)
        return E_INVALIDARG;

    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom);
    szCommand = HeapAlloc(GetProcessHeap(), 0, len);
    if (!szCommand)
        return E_OUTOFMEMORY;

    sprintf(szCommand, szCommandFormat, pszEmailFrom);

    hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
        SMTPTransport_CallbackReadMAILResponse);

    HeapFree(GetProcessHeap(), 0, szCommand);
    return hr;
}

static HRESULT WINAPI SMTPTransport_CommandRCPT(ISMTPTransport2 *iface, LPSTR pszEmailTo)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    const char szCommandFormat[] = "RCPT TO: <%s>\n";
    char *szCommand;
    int len;
    HRESULT hr;

    TRACE("(%s)\n", debugstr_a(pszEmailTo));

    if (!pszEmailTo)
        return E_INVALIDARG;

    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo);
    szCommand = HeapAlloc(GetProcessHeap(), 0, len);
    if (!szCommand)
        return E_OUTOFMEMORY;

    sprintf(szCommand, szCommandFormat, pszEmailTo);

    hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
        SMTPTransport_CallbackReadRCPTResponse);

    HeapFree(GetProcessHeap(), 0, szCommand);
    return hr;
}

static HRESULT WINAPI SMTPTransport_CommandEHLO(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    const char szCommandFormat[] = "EHLO %s\n";
    const char szHostname[] = "localhost"; /* FIXME */
    char *szCommand;
    int len = sizeof(szCommandFormat) - 2 /* "%s" */ + sizeof(szHostname);
    HRESULT hr;

    TRACE("\n");

    szCommand = HeapAlloc(GetProcessHeap(), 0, len);
    if (!szCommand)
        return E_OUTOFMEMORY;

    sprintf(szCommand, szCommandFormat, szHostname);

    hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
        SMTPTransport_CallbackReadResponseDoNothing);

    HeapFree(GetProcessHeap(), 0, szCommand);
    return hr;
}

static HRESULT WINAPI SMTPTransport_CommandHELO(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    const char szCommandFormat[] = "HELO %s\n";
    const char szHostname[] = "localhost"; /* FIXME */
    char *szCommand;
    int len = sizeof(szCommandFormat) - 2 /* "%s" */ + sizeof(szHostname);
    HRESULT hr;

    TRACE("()\n");

    szCommand = HeapAlloc(GetProcessHeap(), 0, len);
    if (!szCommand)
        return E_OUTOFMEMORY;

    sprintf(szCommand, szCommandFormat, szHostname);

    hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
        SMTPTransport_CallbackReadResponseDoNothing);

    HeapFree(GetProcessHeap(), 0, szCommand);
    return hr;
}

static HRESULT WINAPI SMTPTransport_CommandAUTH(ISMTPTransport2 *iface,
    LPSTR pszAuthType)
{
    SMTPTransport *This = (SMTPTransport *)iface;
    const char szCommandFormat[] = "AUTH %s\n";
    char *szCommand;
    int len;
    HRESULT hr;

    TRACE("(%s)\n", debugstr_a(pszAuthType));

    if (!pszAuthType)
        return E_INVALIDARG;

    len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType);
    szCommand = HeapAlloc(GetProcessHeap(), 0, len);
    if (!szCommand)
        return E_OUTOFMEMORY;

    sprintf(szCommand, szCommandFormat, pszAuthType);

    hr = InternetTransport_DoCommand(&This->InetTransport, szCommand,
        SMTPTransport_CallbackReadResponseDoNothing);

    HeapFree(GetProcessHeap(), 0, szCommand);
    return hr;
}

static HRESULT WINAPI SMTPTransport_CommandQUIT(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;

    TRACE("()\n");

    InternetTransport_ChangeStatus(&This->InetTransport, IXP_DISCONNECTING);
    return InternetTransport_DoCommand(&This->InetTransport, "QUIT\n",
        SMTPTransport_CallbackDisconnect);
}

static HRESULT WINAPI SMTPTransport_CommandRSET(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;

    TRACE("()\n");

    return InternetTransport_DoCommand(&This->InetTransport, "RSET\n",
        SMTPTransport_CallbackReadResponseDoNothing);
}

static HRESULT WINAPI SMTPTransport_CommandDATA(ISMTPTransport2 *iface)
{
    SMTPTransport *This = (SMTPTransport *)iface;

    TRACE("()\n");

    return InternetTransport_DoCommand(&This->InetTransport, "DATA\n",
        SMTPTransport_CallbackReadDATAResponse);
}

static HRESULT WINAPI SMTPTransport_CommandDOT(ISMTPTransport2 *iface)
{
    FIXME("()\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SMTPTransport_SendDataStream(ISMTPTransport2 *iface,
    IStream *pStream, ULONG cbSize)
{
    FIXME("(%p, %d)\n", pStream, cbSize);
    return E_NOTIMPL;
}

static HRESULT WINAPI SMTPTransport_SetWindow(ISMTPTransport2 *iface)
{
    FIXME("()\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SMTPTransport_ResetWindow(ISMTPTransport2 *iface)
{
    FIXME("()\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI SMTPTransport_SendMessage2(ISMTPTransport2 *iface, LPSMTPMESSAGE2 pMessage)
{
    FIXME("(%p)\n", pMessage);
    return E_NOTIMPL;
}

static HRESULT WINAPI SMTPTransport_CommandRCPT2(ISMTPTransport2 *iface, LPSTR pszEmailTo,
    INETADDRTYPE atDSN)
{
    FIXME("(%s, %u)\n", pszEmailTo, atDSN);
    return E_NOTIMPL;
}

static const ISMTPTransport2Vtbl SMTPTransport2Vtbl =
{
    SMTPTransport_QueryInterface,
    SMTPTransport_AddRef,
    SMTPTransport_Release,
    SMTPTransport_GetServerInfo,
    SMTPTransport_GetIXPType,
    SMTPTransport_IsState,
    SMTPTransport_InetServerFromAccount,
    SMTPTransport_Connect,
    SMTPTransport_HandsOffCallback,
    SMTPTransport_Disconnect,
    SMTPTransport_DropConnection,
    SMTPTransport_GetStatus,
    SMTPTransport_InitNew,
    SMTPTransport_SendMessage,
    SMTPTransport_CommandMAIL,
    SMTPTransport_CommandRCPT,
    SMTPTransport_CommandEHLO,
    SMTPTransport_CommandHELO,
    SMTPTransport_CommandAUTH,
    SMTPTransport_CommandQUIT,
    SMTPTransport_CommandRSET,
    SMTPTransport_CommandDATA,
    SMTPTransport_CommandDOT,
    SMTPTransport_SendDataStream,
    SMTPTransport_SetWindow,
    SMTPTransport_ResetWindow,
    SMTPTransport_SendMessage2,
    SMTPTransport_CommandRCPT2
};

HRESULT WINAPI CreateSMTPTransport(ISMTPTransport **ppTransport)
{
    HRESULT hr;
    SMTPTransport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;

    This->InetTransport.u.vtblSMTP2 = &SMTPTransport2Vtbl;
    This->refs = 0;
    This->fESMTP = FALSE;
    hr = InternetTransport_Init(&This->InetTransport);
    if (FAILED(hr))
    {
        HeapFree(GetProcessHeap(), 0, This);
        return hr;
    }

    *ppTransport = (ISMTPTransport *)&This->InetTransport.u.vtblSMTP2;
    ISMTPTransport_AddRef(*ppTransport);

    return S_OK;
}


static HRESULT WINAPI SMTPTransportCF_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 SMTPTransportCF_AddRef(LPCLASSFACTORY iface)
{
    return 2; /* non-heap based object */
}

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

static HRESULT WINAPI SMTPTransportCF_CreateInstance(LPCLASSFACTORY iface,
    LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
{
    HRESULT hr;
    ISMTPTransport *pSmtpTransport;

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

    *ppv = NULL;

    if (pUnk)
        return CLASS_E_NOAGGREGATION;

    hr = CreateSMTPTransport(&pSmtpTransport);
    if (FAILED(hr))
        return hr;

    hr = ISMTPTransport_QueryInterface(pSmtpTransport, riid, ppv);
    ISMTPTransport_Release(pSmtpTransport);

    return hr;
}

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

static const IClassFactoryVtbl SMTPTransportCFVtbl =
{
    SMTPTransportCF_QueryInterface,
    SMTPTransportCF_AddRef,
    SMTPTransportCF_Release,
    SMTPTransportCF_CreateInstance,
    SMTPTransportCF_LockServer
};
static const IClassFactoryVtbl *SMTPTransportCF = &SMTPTransportCFVtbl;

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