/*
 * MAPISendMail implementation
 *
 * Copyright 2005 Hans Leidekker
 * Copyright 2009 Owen Rudge 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
 */

#include "config.h"
#include "wine/port.h"

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

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "mapi.h"
#include "winreg.h"
#include "shellapi.h"
#include "shlwapi.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winemapi);

/* Escapes a string for use in mailto: URL */
static char *escape_string(char *in, char *empty_string)
{
    HRESULT res;
    DWORD size;
    char *escaped = NULL;

    if (!in)
        return empty_string;

    size = 1;
    res = UrlEscapeA(in, empty_string, &size, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY);

    if (res == E_POINTER)
    {
        escaped = HeapAlloc(GetProcessHeap(), 0, size);

        if (!escaped)
            return in;

        /* If for some reason UrlEscape fails, just send the original text */
        if (UrlEscapeA(in, escaped, &size, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY) != S_OK)
        {
            HeapFree(GetProcessHeap(), 0, escaped);
            escaped = in;
        }
    }

    return escaped ? escaped : empty_string;
}

/**************************************************************************
 *  MAPISendMail
 *
 * Send a message using a native mail client.
 *
 * PARAMS
 *  session  [I] Handle to a MAPI session.
 *  uiparam  [I] Parent window handle.
 *  message  [I] Pointer to a MAPIMessage structure.
 *  flags    [I] Flags.
 *  reserved [I] Reserved, pass 0.
 *
 * RETURNS
 *  Success: SUCCESS_SUCCESS
 *  Failure: MAPI_E_FAILURE
 *
 */
ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
    lpMapiMessage message, FLAGS flags, ULONG reserved)
{
    ULONG ret = MAPI_E_FAILURE;
    unsigned int i, to_count = 0, cc_count = 0, bcc_count = 0;
    unsigned int to_size = 0, cc_size = 0, bcc_size = 0, subj_size, body_size;

    char *to = NULL, *cc = NULL, *bcc = NULL, *subject = NULL, *body = NULL;
    const char *address;
    static const char format[] =
        "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"";
    static const char smtp[] = "smtp:";
    char *mailto = NULL, *escape = NULL;
    char empty_string[] = "";
    HRESULT res;
    DWORD size;

    TRACE("(0x%08lx 0x%08lx %p 0x%08x 0x%08x)\n", session, uiparam,
           message, flags, reserved);

    if (!message)
        return MAPI_E_FAILURE;

    for (i = 0; i < message->nRecipCount; i++)
    {
        if (!message->lpRecips)
        {
            WARN("No recipients found\n");
            return MAPI_E_FAILURE;
        }

        address = message->lpRecips[i].lpszAddress;

        if (address)
        {
            if (!strncasecmp(address, smtp, sizeof(smtp) - 1))
                address += sizeof(smtp) - 1;

            switch (message->lpRecips[i].ulRecipClass)
            {
                case MAPI_ORIG:
                    TRACE("From: %s\n", debugstr_a(address));
                    break;

                case MAPI_TO:
                    TRACE("To: %s\n", debugstr_a(address));
                    to_size += lstrlenA(address) + 1;
                    break;

                case MAPI_CC:
                    TRACE("Cc: %s\n", debugstr_a(address));
                    cc_size += lstrlenA(address) + 1;
                    break;

                case MAPI_BCC:
                    TRACE("Bcc: %s\n", debugstr_a(address));
                    bcc_size += lstrlenA(address) + 1;
                    break;

                default:
                    TRACE("Unknown recipient class: %d\n",
                           message->lpRecips[i].ulRecipClass);
            }
        }
        else
            FIXME("Name resolution and entry identifiers not supported\n");
    }

    if (message->nFileCount)
    {
        FIXME("Ignoring %u attachments:\n", message->nFileCount);
        for (i = 0; i < message->nFileCount; i++)
            FIXME("\t%s (%s)\n", debugstr_a(message->lpFiles[i].lpszPathName),
                  debugstr_a(message->lpFiles[i].lpszFileName));
    }

    /* Escape subject and body */
    subject = escape_string(message->lpszSubject, empty_string);
    body = escape_string(message->lpszNoteText, empty_string);

    TRACE("Subject: %s\n", debugstr_a(subject));
    TRACE("Body: %s\n", debugstr_a(body));

    subj_size = lstrlenA(subject);
    body_size = lstrlenA(body);

    ret = MAPI_E_INSUFFICIENT_MEMORY;

    if (to_size)
    {
        to = HeapAlloc(GetProcessHeap(), 0, to_size);

        if (!to)
            goto exit;

        to[0] = 0;
    }

    if (cc_size)
    {
        cc = HeapAlloc(GetProcessHeap(), 0, cc_size);

        if (!cc)
            goto exit;

        cc[0] = 0;
    }

    if (bcc_size)
    {
        bcc = HeapAlloc(GetProcessHeap(), 0, bcc_size);

        if (!bcc)
            goto exit;

        bcc[0] = 0;
    }

    if (message->lpOriginator)
        TRACE("From: %s\n", debugstr_a(message->lpOriginator->lpszAddress));

    for (i = 0; i < message->nRecipCount; i++)
    {
        address = message->lpRecips[i].lpszAddress;

        if (address)
        {
            if (!strncasecmp(address, smtp, sizeof(smtp) - 1))
                address += sizeof(smtp) - 1;

            switch (message->lpRecips[i].ulRecipClass)
            {
                case MAPI_TO:
                    if (to_count)
                        lstrcatA(to, ",");

                    lstrcatA(to, address);
                    to_count++;
                    break;

                case MAPI_CC:
                    if (cc_count)
                        lstrcatA(cc, ",");

                    lstrcatA(cc, address);
                    cc_count++;
                    break;

                case MAPI_BCC:
                    if (bcc_count)
                        lstrcatA(bcc, ",");

                    lstrcatA(bcc, address);
                    bcc_count++;
                    break;
            }
        }
    }
    ret = MAPI_E_FAILURE;
    size = sizeof(format) + to_size + cc_size + bcc_size + subj_size + body_size;

    mailto = HeapAlloc(GetProcessHeap(), 0, size);

    if (!mailto)
        goto exit;

    sprintf(mailto, format, to ? to : "", subject, cc ? cc : "", bcc ? bcc : "", body);

    size = 1;
    res = UrlEscapeA(mailto, empty_string, &size, URL_ESCAPE_SPACES_ONLY);

    if (res != E_POINTER)
        goto exit;

    escape = HeapAlloc(GetProcessHeap(), 0, size);

    if (!escape)
        goto exit;

    res = UrlEscapeA(mailto, escape, &size, URL_ESCAPE_SPACES_ONLY);

    if (res != S_OK)
        goto exit;

    TRACE("Executing winebrowser.exe with parameters '%s'\n", debugstr_a(escape));

    if ((UINT_PTR) ShellExecuteA(NULL, "open", "winebrowser.exe", escape, NULL, 0) > 32)
        ret = SUCCESS_SUCCESS;

exit:
    HeapFree(GetProcessHeap(), 0, to);
    HeapFree(GetProcessHeap(), 0, cc);
    HeapFree(GetProcessHeap(), 0, bcc);
    HeapFree(GetProcessHeap(), 0, mailto);
    HeapFree(GetProcessHeap(), 0, escape);

    if (subject != empty_string)
        HeapFree(GetProcessHeap(), 0, subject);

    if (body != empty_string)
        HeapFree(GetProcessHeap(), 0, body);

    return ret;
}

ULONG WINAPI MAPISendDocuments(ULONG_PTR uiparam, LPSTR delim, LPSTR paths,
    LPSTR filenames, ULONG reserved)
{
    return MAPI_E_NOT_SUPPORTED;
}
