/*
 * winebrowser - winelib app to launch native OS browser or mail client.
 *
 * Copyright (C) 2004 Chris Morgan
 * Copyright (C) 2005 Hans Leidekker
 *
 * 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
 *
 * NOTES:
 *  Winebrowser is a winelib application that will start the appropriate
 *  native browser or mail client for a wine installation that lacks a 
 *  windows browser/mail client. For example, you will be able to open
 *  urls via native mozilla if no browser has yet been installed in wine.
 *
 *  The application to launch is chosen from a default set or, if set,
 *  taken from a registry key.
 *  
 *  The argument may be a regular Windows file name, a file URL, an
 *  URL or a mailto URL. In the first three cases the argument
 *  will be fed to a web browser. In the last case the argument is fed
 *  to a mail client. A mailto URL is composed as follows:
 *
 *   mailto:[E-MAIL]?subject=[TOPIC]&cc=[E-MAIL]&bcc=[E-MAIL]&body=[TEXT]
 */

#define WIN32_LEAN_AND_MEAN

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

#include <windows.h>
#include <shlwapi.h>
#include <ddeml.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

WINE_DEFAULT_DEBUG_CHANNEL(winebrowser);

typedef LPSTR (*wine_get_unix_file_name_t)(LPCWSTR unixname);

static const WCHAR browser_key[] =
    {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
     'W','i','n','e','B','r','o','w','s','e','r',0};

static char *strdup_unixcp( const WCHAR *str )
{
    char *ret;
    int len = WideCharToMultiByte( CP_UNIXCP, 0, str, -1, NULL, 0, NULL, NULL );
    if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
        WideCharToMultiByte( CP_UNIXCP, 0, str, -1, ret, len, NULL, NULL );
    return ret;
}

static WCHAR *strdupW( const WCHAR *src )
{
    WCHAR *dst;
    if (!src) return NULL;
    if ((dst = HeapAlloc( GetProcessHeap(), 0, (strlenW( src ) + 1) * sizeof(WCHAR) )))
        strcpyW( dst, src );
    return dst;
}

/* try to launch a unix app from a comma separated string of app names */
static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
{
    char *app, *applist, *cmdline;
    const char *argv_new[3];

    if (!(applist = strdup_unixcp( candidates ))) return 1;
    if (!(cmdline = strdup_unixcp( argv1 )))
    {
        HeapFree( GetProcessHeap(), 0, applist );
        return 1;
    }
    app = strtok( applist, "," );
    while (app)
    {
        WINE_TRACE( "Considering: %s\n", wine_dbgstr_a(app) );
        WINE_TRACE( "argv[1]: %s\n", wine_dbgstr_a(cmdline) );

        argv_new[0] = app;
        argv_new[1] = cmdline;
        argv_new[2] = NULL;

        spawnvp( _P_OVERLAY, app, argv_new );  /* only returns on error */
        app = strtok( NULL, "," );  /* grab the next app */
    }
    WINE_ERR( "could not find a suitable app to run\n" );

    HeapFree( GetProcessHeap(), 0, applist );
    HeapFree( GetProcessHeap(), 0, cmdline );
    return 1;
}

static int open_http_url( const WCHAR *url )
{
#ifdef __APPLE__
    static const WCHAR defaultbrowsers[] =
        { '/', 'u', 's', 'r', '/', 'b', 'i', 'n', '/', 'o', 'p', 'e', 'n', 0 };
#else
    static const WCHAR defaultbrowsers[] =
        {'x','d','g','-','o','p','e','n',',','f','i','r','e','f','o','x',',',
         'k','o','n','q','u','e','r','o','r',',','m','o','z','i','l','l','a',',',
         'n','e','t','s','c','a','p','e',',','g','a','l','e','o','n',',',
         'o','p','e','r','a',',','d','i','l','l','o',0};
#endif
    static const WCHAR browsersW[] =
        {'B','r','o','w','s','e','r','s',0};

    WCHAR browsers[256];
    DWORD length, type;
    HKEY key;
    LONG r;

    length = sizeof(browsers);
    /* @@ Wine registry key: HKCU\Software\Wine\WineBrowser */
    if  (!(r = RegOpenKeyW( HKEY_CURRENT_USER, browser_key, &key )))
    {
        r = RegQueryValueExW( key, browsersW, 0, &type, (LPBYTE)browsers, &length );
        RegCloseKey( key );
    }
    if (r != ERROR_SUCCESS)
        strcpyW( browsers, defaultbrowsers );

    return launch_app( browsers, url );
}

static int open_mailto_url( const WCHAR *url )
{
#ifdef __APPLE__
    static const WCHAR defaultmailers[] =
        { '/', 'u', 's', 'r', '/', 'b', 'i', 'n', '/', 'o', 'p', 'e', 'n', 0 };
#else
    static const WCHAR defaultmailers[] =
        {'x','d','g','-','e','m','a','i','l',',',
         'm','o','z','i','l','l','a','-','t','h','u','n','d','e','r','b','i','r','d',',',
         't','h','u','n','d','e','r','b','i','r','d',',',
         'e','v','o','l','u','t','i','o','n',0};
#endif
    static const WCHAR mailersW[] =
        {'M','a','i','l','e','r','s',0};

    WCHAR mailers[256];
    DWORD length, type;
    HKEY key;
    LONG r;

    length = sizeof(mailers);
    /* @@ Wine registry key: HKCU\Software\Wine\WineBrowser */
    if (!(r = RegOpenKeyW( HKEY_CURRENT_USER, browser_key, &key )))
    {
        r = RegQueryValueExW( key, mailersW, 0, &type, (LPBYTE)mailers, &length );
        RegCloseKey( key );
    }
    if (r != ERROR_SUCCESS)
        strcpyW( mailers, defaultmailers );

    return launch_app( mailers, url );
}

/*****************************************************************************
 * DDE helper functions.
 */

static WCHAR *ddeString = NULL;
static HSZ hszTopic = 0, hszReturn = 0;
static DWORD ddeInst = 0;

/* Dde callback, save the execute or request string for processing */
static HDDEDATA CALLBACK ddeCb(UINT uType, UINT uFmt, HCONV hConv,
                                HSZ hsz1, HSZ hsz2, HDDEDATA hData,
                                ULONG_PTR dwData1, ULONG_PTR dwData2)
{
    DWORD size = 0, ret = 0;

    WINE_TRACE("dde_cb: %04x, %04x, %p, %p, %p, %p, %08lx, %08lx\n",
               uType, uFmt, hConv, hsz1, hsz2, hData, dwData1, dwData2);

    switch (uType)
    {
        case XTYP_CONNECT:
            if (!DdeCmpStringHandles(hsz1, hszTopic))
                return (HDDEDATA)TRUE;
            return (HDDEDATA)FALSE;

        case XTYP_EXECUTE:
            if (!(size = DdeGetData(hData, NULL, 0, 0)))
                WINE_ERR("DdeGetData returned zero size of execute string\n");
            else if (!(ddeString = HeapAlloc(GetProcessHeap(), 0, size)))
                WINE_ERR("Out of memory\n");
            else if (DdeGetData(hData, (LPBYTE)ddeString, size, 0) != size)
                WINE_WARN("DdeGetData did not return %d bytes\n", size);
            DdeFreeDataHandle(hData);
            return (HDDEDATA)DDE_FACK;

        case XTYP_REQUEST:
            ret = -3; /* error */
            if (!(size = DdeQueryStringW(ddeInst, hsz2, NULL, 0, CP_WINUNICODE)))
                WINE_ERR("DdeQueryString returned zero size of request string\n");
            else if (!(ddeString = HeapAlloc(GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR))))
                WINE_ERR("Out of memory\n");
            else if (DdeQueryStringW(ddeInst, hsz2, ddeString, size + 1, CP_WINUNICODE) != size)
                WINE_WARN("DdeQueryString did not return %d characters\n", size);
            else
                ret = -2; /* acknowledgment */
            return DdeCreateDataHandle(ddeInst, (LPBYTE)&ret, sizeof(ret), 0,
                                       hszReturn, CF_TEXT, 0);

        default:
            return NULL;
    }
}

static WCHAR *get_url_from_dde(void)
{
    static const WCHAR szApplication[] = {'I','E','x','p','l','o','r','e',0};
    static const WCHAR szTopic[] = {'W','W','W','_','O','p','e','n','U','R','L',0};
    static const WCHAR szReturn[] = {'R','e','t','u','r','n',0};

    HSZ hszApplication = 0;
    UINT_PTR timer = 0;
    int rc;
    WCHAR *ret = NULL;

    rc = DdeInitializeW(&ddeInst, ddeCb, CBF_SKIP_ALLNOTIFICATIONS | CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
    if (rc != DMLERR_NO_ERROR)
    {
        WINE_ERR("Unable to initialize DDE, DdeInitialize returned %d\n", rc);
        goto done;
    }

    hszApplication = DdeCreateStringHandleW(ddeInst, szApplication, CP_WINUNICODE);
    if (!hszApplication)
    {
        WINE_ERR("Unable to initialize DDE, DdeCreateStringHandle failed\n");
        goto done;
    }

    hszTopic = DdeCreateStringHandleW(ddeInst, szTopic, CP_WINUNICODE);
    if (!hszTopic)
    {
        WINE_ERR("Unable to initialize DDE, DdeCreateStringHandle failed\n");
        goto done;
    }

    hszReturn = DdeCreateStringHandleW(ddeInst, szReturn, CP_WINUNICODE);
    if (!hszReturn)
    {
        WINE_ERR("Unable to initialize DDE, DdeCreateStringHandle failed\n");
        goto done;
    }

    if (!DdeNameService(ddeInst, hszApplication, 0, DNS_REGISTER))
    {
        WINE_ERR("Unable to initialize DDE, DdeNameService failed\n");
        goto done;
    }

    timer = SetTimer(NULL, 0, 5000, NULL);
    if (!timer)
    {
        WINE_ERR("SetTimer failed to create timer\n");
        goto done;
    }

    while (!ddeString)
    {
        MSG msg;
        if (!GetMessageW(&msg, NULL, 0, 0)) break;
        if (msg.message == WM_TIMER) break;
        DispatchMessageW(&msg);
    }

    if (ddeString)
    {
        if (*ddeString == '"')
        {
            WCHAR *endquote = strchrW(ddeString + 1, '"');
            if (!endquote)
            {
                WINE_ERR("Unable to retrieve URL from string %s\n", wine_dbgstr_w(ddeString));
                goto done;
            }
            *endquote = 0;
            ret = ddeString+1;
        }
        else
            ret = ddeString;
    }

done:
    if (timer) KillTimer(NULL, timer);
    if (ddeInst)
    {
        if (hszTopic && hszApplication) DdeNameService(ddeInst, hszApplication, 0, DNS_UNREGISTER);
        if (hszReturn) DdeFreeStringHandle(ddeInst, hszReturn);
        if (hszTopic) DdeFreeStringHandle(ddeInst, hszTopic);
        if (hszApplication) DdeFreeStringHandle(ddeInst, hszApplication);
        DdeUninitialize(ddeInst);
    }
    return ret;
}

/*****************************************************************************
 * Main entry point. This is a console application so we have a wmain() not a
 * winmain().
 */
int wmain(int argc, WCHAR *argv[])
{
    static const WCHAR nohomeW[] = {'-','n','o','h','o','m','e',0};
    static const WCHAR mailtoW[] = {'m','a','i','l','t','o',':',0};
    static const WCHAR fileW[] = {'f','i','l','e',':',0};

    WCHAR *p, *filenameW = NULL, *fileurlW = NULL, *url = argv[1];
    wine_get_unix_file_name_t wine_get_unix_file_name_ptr;
    int ret = 1;

    /* DDE used only if -nohome is specified; avoids delay in printing usage info
     * when no parameters are passed */
    if (url && !strcmpiW( url, nohomeW ))
        url = argc > 2 ? argv[2] : get_url_from_dde();

    if (!url)
    {
        WINE_ERR( "Usage: winebrowser URL\n" );
        goto done;
    }

    /* handle an RFC1738 file URL */
    if (!strncmpiW( url, fileW, 5 ))
    {
        DWORD len = strlenW( url ) + 1;

        if (UrlUnescapeW( url, NULL, &len, URL_UNESCAPE_INPLACE ) != S_OK)
        {
            WINE_ERR( "unescaping URL failed: %s\n", wine_dbgstr_w(url) );
            goto done;
        }

        /* look for a Windows path after 'file:' */
        p = url + 5;
        while (*p)
        {
            if (isalphaW( p[0] ) && (p[1] == ':' || p[1] == '|')) break;
            p++;
        }
        if (!*p)
        {
            WINE_ERR( "no valid Windows path in: %s\n", wine_dbgstr_w(url) );
            goto done;
        }

        if (p[1] == '|') p[1] = ':';
        url = p;
 
        while (*p)
        {
            if (*p == '/') *p = '\\';
            p++;
        }
    }

    /* check if the argument is a local file */
    wine_get_unix_file_name_ptr = (wine_get_unix_file_name_t)
        GetProcAddress( GetModuleHandleA( "KERNEL32" ), "wine_get_unix_file_name" );

    if (wine_get_unix_file_name_ptr == NULL)
    {
        WINE_ERR( "cannot get the address of 'wine_get_unix_file_name'\n" );
    }
    else
    {
        char *unixpath;
        WCHAR c = 0;

        if (!(filenameW = strdupW( url ))) goto done;
        if ((p = strchrW( filenameW, '?' )) || (p = strchrW( filenameW, '#' )))
        {
            c = *p;
            *p = 0;
        }

        if ((unixpath = wine_get_unix_file_name_ptr( filenameW )))
        {
            struct stat dummy;
            if (stat( unixpath, &dummy ) >= 0)
            {
                static const WCHAR schemeW[] = {'f','i','l','e',':','/','/',0};
                int len, len_scheme;

                len = len_scheme = strlenW( schemeW );
                len += MultiByteToWideChar( CP_UNIXCP, 0, unixpath, -1, NULL, 0 );
                if (p)
                {
                    *p = c;
                    len += strlenW( p );
                }

                if (!(fileurlW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) goto done;

                strcpyW( fileurlW, schemeW );
                MultiByteToWideChar( CP_UNIXCP, 0, unixpath, -1, fileurlW + len_scheme, len - len_scheme );
                if (p) strcatW( fileurlW, p );

                ret = open_http_url( fileurlW );
                goto done;
            }
        }
    }

    if (!strncmpiW( url, mailtoW, 7 ))
        ret = open_mailto_url( url );
    else
        /* let the browser decide how to handle the given url */
        ret = open_http_url( url );

done:
    HeapFree(GetProcessHeap(), 0, ddeString);
    HeapFree( GetProcessHeap(), 0, filenameW );
    HeapFree( GetProcessHeap(), 0, fileurlW );
    return ret;
}
