/*
 * MIME OLE International interface
 *
 * Copyright 2008 Huw Davies 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 "winuser.h"
#include "winnls.h"
#include "objbase.h"
#include "ole2.h"
#include "mimeole.h"
#include "mlang.h"

#include "wine/list.h"
#include "wine/unicode.h"
#include "wine/debug.h"

#include "inetcomm_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);

typedef struct
{
    struct list entry;
    INETCSETINFO cs_info;
} charset_entry;

typedef struct
{
    const IMimeInternationalVtbl *lpVtbl;
    LONG refs;
    CRITICAL_SECTION cs;

    struct list charsets;
    LONG next_charset_handle;
    HCHARSET default_charset;
} internat;

static inline internat *impl_from_IMimeInternational( IMimeInternational *iface )
{
    return (internat *)((char*)iface - FIELD_OFFSET(internat, lpVtbl));
}

static inline HRESULT get_mlang(IMultiLanguage **ml)
{
    return CoCreateInstance(&CLSID_CMultiLanguage, NULL,  CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER,
                            &IID_IMultiLanguage, (void **)ml);
}

static HRESULT WINAPI MimeInternat_QueryInterface( IMimeInternational *iface, REFIID riid, LPVOID *ppobj )
{
    if (IsEqualGUID(riid, &IID_IUnknown) ||
        IsEqualGUID(riid, &IID_IMimeInternational))
    {
        IMimeInternational_AddRef( iface );
        *ppobj = iface;
        return S_OK;
    }

    FIXME("interface %s not implemented\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI MimeInternat_AddRef( IMimeInternational *iface )
{
    internat *This = impl_from_IMimeInternational( iface );
    return InterlockedIncrement(&This->refs);
}

static ULONG WINAPI MimeInternat_Release( IMimeInternational *iface )
{
    internat *This = impl_from_IMimeInternational( iface );
    ULONG refs;

    refs = InterlockedDecrement(&This->refs);
    if (!refs)
    {
        charset_entry *charset, *cursor2;

        LIST_FOR_EACH_ENTRY_SAFE(charset, cursor2, &This->charsets, charset_entry, entry)
        {
            list_remove(&charset->entry);
            HeapFree(GetProcessHeap(), 0, charset);
        }
        HeapFree(GetProcessHeap(), 0, This);
    }

    return refs;
}

static HRESULT WINAPI MimeInternat_SetDefaultCharset(IMimeInternational *iface, HCHARSET hCharset)
{
    internat *This = impl_from_IMimeInternational( iface );

    TRACE("(%p)->(%p)\n", iface, hCharset);

    if(hCharset == NULL) return E_INVALIDARG;
    /* FIXME check hCharset is valid */

    InterlockedExchangePointer(&This->default_charset, hCharset);

    return S_OK;
}

static HRESULT WINAPI MimeInternat_GetDefaultCharset(IMimeInternational *iface, LPHCHARSET phCharset)
{
    internat *This = impl_from_IMimeInternational( iface );
    HRESULT hr = S_OK;

    TRACE("(%p)->(%p)\n", iface, phCharset);

    if(This->default_charset == NULL)
    {
        HCHARSET hcs;
        hr = IMimeInternational_GetCodePageCharset(iface, GetACP(), CHARSET_BODY, &hcs);
        if(SUCCEEDED(hr))
            InterlockedCompareExchangePointer(&This->default_charset, hcs, NULL);
    }
    *phCharset = This->default_charset;

    return hr;
}

static HRESULT mlang_getcodepageinfo(UINT cp, MIMECPINFO *mlang_cp_info)
{
    HRESULT hr;
    IMultiLanguage *ml;

    hr = get_mlang(&ml);

    if(SUCCEEDED(hr))
    {
        hr = IMultiLanguage_GetCodePageInfo(ml, cp, mlang_cp_info);
        IMultiLanguage_Release(ml);
    }
    return hr;
}

static HRESULT WINAPI MimeInternat_GetCodePageCharset(IMimeInternational *iface, CODEPAGEID cpiCodePage,
                                                      CHARSETTYPE ctCsetType,
                                                      LPHCHARSET phCharset)
{
    HRESULT hr;
    MIMECPINFO mlang_cp_info;

    TRACE("(%p)->(%d, %d, %p)\n", iface, cpiCodePage, ctCsetType, phCharset);

    *phCharset = NULL;

    hr = mlang_getcodepageinfo(cpiCodePage, &mlang_cp_info);
    if(SUCCEEDED(hr))
    {
        const WCHAR *charset_nameW = NULL;
        char *charset_name;
        DWORD len;

        switch(ctCsetType)
        {
        case CHARSET_BODY:
            charset_nameW = mlang_cp_info.wszBodyCharset;
            break;
        case CHARSET_HEADER:
            charset_nameW = mlang_cp_info.wszHeaderCharset;
            break;
        case CHARSET_WEB:
            charset_nameW = mlang_cp_info.wszWebCharset;
            break;
        default:
            return MIME_E_INVALID_CHARSET_TYPE;
        }
        len = WideCharToMultiByte(CP_ACP, 0, charset_nameW, -1, NULL, 0, NULL, NULL);
        charset_name = HeapAlloc(GetProcessHeap(), 0, len);
        WideCharToMultiByte(CP_ACP, 0, charset_nameW, -1, charset_name, len, NULL, NULL);
        hr = IMimeInternational_FindCharset(iface, charset_name, phCharset);
        HeapFree(GetProcessHeap(), 0, charset_name);
    }
    return hr;
}

static HRESULT mlang_getcsetinfo(const char *charset, MIMECSETINFO *mlang_info)
{
    DWORD len = MultiByteToWideChar(CP_ACP, 0, charset, -1, NULL, 0);
    BSTR bstr = SysAllocStringLen(NULL, len - 1);
    HRESULT hr;
    IMultiLanguage *ml;

    MultiByteToWideChar(CP_ACP, 0, charset, -1, bstr, len);

    hr = get_mlang(&ml);

    if(SUCCEEDED(hr))
    {
        hr = IMultiLanguage_GetCharsetInfo(ml, bstr, mlang_info);
        IMultiLanguage_Release(ml);
    }
    SysFreeString(bstr);
    if(FAILED(hr)) hr = MIME_E_NOT_FOUND;
    return hr;
}

static HCHARSET add_charset(struct list *list, MIMECSETINFO *mlang_info, HCHARSET handle)
{
    charset_entry *charset = HeapAlloc(GetProcessHeap(), 0, sizeof(*charset));

    WideCharToMultiByte(CP_ACP, 0, mlang_info->wszCharset, -1,
                        charset->cs_info.szName, sizeof(charset->cs_info.szName), NULL, NULL);
    charset->cs_info.cpiWindows = mlang_info->uiCodePage;
    charset->cs_info.cpiInternet = mlang_info->uiInternetEncoding;
    charset->cs_info.hCharset = handle;
    charset->cs_info.dwReserved1 = 0;
    list_add_head(list, &charset->entry);

    return charset->cs_info.hCharset;
}

static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR pszCharset,
                                               LPHCHARSET phCharset)
{
    internat *This = impl_from_IMimeInternational( iface );
    HRESULT hr = MIME_E_NOT_FOUND;
    charset_entry *charset;

    TRACE("(%p)->(%s, %p)\n", iface, debugstr_a(pszCharset), phCharset);

    *phCharset = NULL;

    EnterCriticalSection(&This->cs);

    LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry)
    {
        if(!lstrcmpiA(charset->cs_info.szName, pszCharset))
        {
            *phCharset = charset->cs_info.hCharset;
            hr = S_OK;
            break;
        }
    }

    if(hr == MIME_E_NOT_FOUND)
    {
        MIMECSETINFO mlang_info;

        LeaveCriticalSection(&This->cs);
        hr = mlang_getcsetinfo(pszCharset, &mlang_info);
        EnterCriticalSection(&This->cs);

        if(SUCCEEDED(hr))
            *phCharset = add_charset(&This->charsets, &mlang_info,
                                     UlongToHandle(InterlockedIncrement(&This->next_charset_handle)));
    }

    LeaveCriticalSection(&This->cs);
    return hr;
}

static HRESULT WINAPI MimeInternat_GetCharsetInfo(IMimeInternational *iface, HCHARSET hCharset,
                                                  LPINETCSETINFO pCsetInfo)
{
    internat *This = impl_from_IMimeInternational( iface );
    HRESULT hr = MIME_E_INVALID_HANDLE;
    charset_entry *charset;

    TRACE("(%p)->(%p, %p)\n", iface, hCharset, pCsetInfo);

    EnterCriticalSection(&This->cs);

    LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry)
    {
        if(charset->cs_info.hCharset ==  hCharset)
        {
            *pCsetInfo = charset->cs_info;
            hr = S_OK;
            break;
        }
    }

    LeaveCriticalSection(&This->cs);

    return hr;
}

static HRESULT WINAPI MimeInternat_GetCodePageInfo(IMimeInternational *iface, CODEPAGEID cpiCodePage,
                                                   LPCODEPAGEINFO pCodePageInfo)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeInternat_CanConvertCodePages(IMimeInternational *iface, CODEPAGEID cpiSource,
                                                       CODEPAGEID cpiDest)
{
    HRESULT hr;
    IMultiLanguage *ml;

    TRACE("(%p)->(%d, %d)\n", iface, cpiSource, cpiDest);

    /* Could call mlang.IsConvertINetStringAvailable() to avoid the COM overhead if need be. */

    hr = get_mlang(&ml);
    if(SUCCEEDED(hr))
    {
        hr = IMultiLanguage_IsConvertible(ml, cpiSource, cpiDest);
        IMultiLanguage_Release(ml);
    }

    return hr;
}

static HRESULT WINAPI MimeInternat_DecodeHeader(IMimeInternational *iface, HCHARSET hCharset,
                                                LPCSTR pszData,
                                                LPPROPVARIANT pDecoded,
                                                LPRFC1522INFO pRfc1522Info)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeInternat_EncodeHeader(IMimeInternational *iface, HCHARSET hCharset,
                                                LPPROPVARIANT pData,
                                                LPSTR *ppszEncoded,
                                                LPRFC1522INFO pRfc1522Info)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeInternat_ConvertBuffer(IMimeInternational *iface, CODEPAGEID cpiSource,
                                                 CODEPAGEID cpiDest, LPBLOB pIn, LPBLOB pOut,
                                                 ULONG *pcbRead)
{
    HRESULT hr;
    IMultiLanguage *ml;

    TRACE("(%p)->(%d, %d, %p, %p, %p)\n", iface, cpiSource, cpiDest, pIn, pOut, pcbRead);

    *pcbRead = 0;
    pOut->cbSize = 0;

    /* Could call mlang.ConvertINetString() to avoid the COM overhead if need be. */

    hr = get_mlang(&ml);
    if(SUCCEEDED(hr))
    {
        DWORD mode = 0;
        UINT in_size = pIn->cbSize, out_size;

        hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, pIn->pBlobData, &in_size,
                                          NULL, &out_size);
        if(hr == S_OK) /* S_FALSE means the conversion could not be performed */
        {
            pOut->pBlobData = CoTaskMemAlloc(out_size);
            if(!pOut->pBlobData)
                hr = E_OUTOFMEMORY;
            else
            {
                mode = 0;
                in_size = pIn->cbSize;
                hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, pIn->pBlobData, &in_size,
                                                  pOut->pBlobData, &out_size);

                if(hr == S_OK)
                {
                    *pcbRead = in_size;
                    pOut->cbSize = out_size;
                }
                else
                    CoTaskMemFree(pOut->pBlobData);
            }
        }
        IMultiLanguage_Release(ml);
    }

    return hr;
}

static HRESULT WINAPI MimeInternat_ConvertString(IMimeInternational *iface, CODEPAGEID cpiSource,
                                                 CODEPAGEID cpiDest, LPPROPVARIANT pIn,
                                                 LPPROPVARIANT pOut)
{
    HRESULT hr;
    int src_len;
    IMultiLanguage *ml;

    TRACE("(%p)->(%d, %d, %p %p)\n", iface, cpiSource, cpiDest, pIn, pOut);

    switch(pIn->vt)
    {
    case VT_LPSTR:
        if(cpiSource == CP_UNICODE) cpiSource = GetACP();
        src_len = strlen(pIn->u.pszVal);
        break;
    case VT_LPWSTR:
        cpiSource = CP_UNICODE;
        src_len = strlenW(pIn->u.pwszVal) * sizeof(WCHAR);
        break;
    default:
        return E_INVALIDARG;
    }

    hr = get_mlang(&ml);
    if(SUCCEEDED(hr))
    {
        DWORD mode = 0;
        UINT in_size = src_len, out_size;

        hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, (BYTE*)pIn->u.pszVal, &in_size,
                                          NULL, &out_size);
        if(hr == S_OK) /* S_FALSE means the conversion could not be performed */
        {
            out_size += (cpiDest == CP_UNICODE) ? sizeof(WCHAR) : sizeof(char);

            pOut->u.pszVal = CoTaskMemAlloc(out_size);
            if(!pOut->u.pszVal)
                hr = E_OUTOFMEMORY;
            else
            {
                mode = 0;
                in_size = src_len;
                hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, (BYTE*)pIn->u.pszVal, &in_size,
                                                  (BYTE*)pOut->u.pszVal, &out_size);

                if(hr == S_OK)
                {
                    if(cpiDest == CP_UNICODE)
                    {
                        pOut->u.pwszVal[out_size / sizeof(WCHAR)] = 0;
                        pOut->vt = VT_LPWSTR;
                    }
                    else
                    {
                        pOut->u.pszVal[out_size] = '\0';
                        pOut->vt = VT_LPSTR;
                    }
                }
                else
                    CoTaskMemFree(pOut->u.pszVal);
            }
        }
        IMultiLanguage_Release(ml);
    }
    return hr;
}

static HRESULT WINAPI MimeInternat_MLANG_ConvertInetReset(IMimeInternational *iface)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeInternat_MLANG_ConvertInetString(IMimeInternational *iface, CODEPAGEID cpiSource,
                                                           CODEPAGEID cpiDest,
                                                           LPCSTR pSource,
                                                           int *pnSizeOfSource,
                                                           LPSTR pDestination,
                                                           int *pnDstSize)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeInternat_Rfc1522Decode(IMimeInternational *iface, LPCSTR pszValue,
                                                 LPSTR pszCharset,
                                                 ULONG cchmax,
                                                 LPSTR *ppszDecoded)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI MimeInternat_Rfc1522Encode(IMimeInternational *iface, LPCSTR pszValue,
                                                 HCHARSET hCharset,
                                                 LPSTR *ppszEncoded)
{
    FIXME("stub\n");
    return E_NOTIMPL;
}

static IMimeInternationalVtbl mime_internat_vtbl =
{
    MimeInternat_QueryInterface,
    MimeInternat_AddRef,
    MimeInternat_Release,
    MimeInternat_SetDefaultCharset,
    MimeInternat_GetDefaultCharset,
    MimeInternat_GetCodePageCharset,
    MimeInternat_FindCharset,
    MimeInternat_GetCharsetInfo,
    MimeInternat_GetCodePageInfo,
    MimeInternat_CanConvertCodePages,
    MimeInternat_DecodeHeader,
    MimeInternat_EncodeHeader,
    MimeInternat_ConvertBuffer,
    MimeInternat_ConvertString,
    MimeInternat_MLANG_ConvertInetReset,
    MimeInternat_MLANG_ConvertInetString,
    MimeInternat_Rfc1522Decode,
    MimeInternat_Rfc1522Encode
};

static internat *global_internat;

HRESULT MimeInternational_Construct(IMimeInternational **internat)
{
    global_internat = HeapAlloc(GetProcessHeap(), 0, sizeof(*global_internat));
    global_internat->lpVtbl = &mime_internat_vtbl;
    global_internat->refs = 0;
    InitializeCriticalSection(&global_internat->cs);

    list_init(&global_internat->charsets);
    global_internat->next_charset_handle = 0;
    global_internat->default_charset = NULL;

    *internat = (IMimeInternational*)&global_internat->lpVtbl;

    IMimeInternational_AddRef(*internat);
    return S_OK;
}

HRESULT WINAPI MimeOleGetInternat(IMimeInternational **internat)
{
    TRACE("(%p)\n", internat);

    *internat = (IMimeInternational *)&global_internat->lpVtbl;
    IMimeInternational_AddRef(*internat);
    return S_OK;
}

HRESULT WINAPI MimeOleFindCharset(LPCSTR name, LPHCHARSET charset)
{
    IMimeInternational *internat;
    HRESULT hr;

    TRACE("(%s, %p)\n", debugstr_a(name), charset);

    hr = MimeOleGetInternat(&internat);
    if(SUCCEEDED(hr))
    {
        hr = IMimeInternational_FindCharset(internat, name, charset);
        IMimeInternational_Release(internat);
    }
    return hr;
}

HRESULT WINAPI MimeOleGetCharsetInfo(HCHARSET hCharset, LPINETCSETINFO pCsetInfo)
{
    IMimeInternational *internat;
    HRESULT hr;

    TRACE("(%p, %p)\n", hCharset, pCsetInfo);

    hr = MimeOleGetInternat(&internat);
    if(SUCCEEDED(hr))
    {
        hr = IMimeInternational_GetCharsetInfo(internat, hCharset, pCsetInfo);
        IMimeInternational_Release(internat);
    }
    return hr;
}

HRESULT WINAPI MimeOleGetDefaultCharset(LPHCHARSET charset)
{
    IMimeInternational *internat;
    HRESULT hr;

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

    hr = MimeOleGetInternat(&internat);
    if(SUCCEEDED(hr))
    {
        hr = IMimeInternational_GetDefaultCharset(internat, charset);
        IMimeInternational_Release(internat);
    }
    return hr;
}
