/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * Copyright 2005 Mike McCormack for CodeWeavers
 * Copyright 2005 Aric Stewart 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
 */

/*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/msiformatrecord.asp 
 */

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

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "msi.h"
#include "winnls.h"
#include "objbase.h"
#include "oleauto.h"

#include "msipriv.h"
#include "msiserver.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);


static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 
                                     WCHAR** data, DWORD len, MSIRECORD* record,
                                     BOOL* in_group);


static LPWSTR build_default_format(const MSIRECORD* record)
{
    int i;  
    int count;
    LPWSTR rc, buf;
    static const WCHAR fmt[] = {'%','i',':',' ','%','s',' ',0};
    static const WCHAR fmt_null[] = {'%','i',':',' ',' ',0};
    static const WCHAR fmt_index[] = {'%','i',0};
    LPCWSTR str;
    WCHAR index[10];
    DWORD size, max_len, len;

    count = MSI_RecordGetFieldCount(record);

    max_len = MAX_PATH;
    buf = msi_alloc((max_len + 1) * sizeof(WCHAR));

    rc = NULL;
    size = 1;
    for (i = 1; i <= count; i++)
    {
        sprintfW(index,fmt_index,i);
        str = MSI_RecordGetString(record, i);
        len = (str) ? lstrlenW(str) : 0;
        len += (sizeof(fmt_null) - 3) + lstrlenW(index);
        size += len;

        if (len > max_len)
        {
            max_len = len;
            buf = msi_realloc(buf, (max_len + 1) * sizeof(WCHAR));
            if (!buf) return NULL;
        }

        if (str)
            sprintfW(buf,fmt,i,str);
        else
            sprintfW(buf,fmt_null,i);

        if (!rc)
        {
            rc = msi_alloc(size * sizeof(WCHAR));
            lstrcpyW(rc, buf);
        }
        else
        {
            rc = msi_realloc(rc, size * sizeof(WCHAR));
            lstrcatW(rc, buf);
        }
    }
    msi_free(buf);
    return rc;
}

static const WCHAR* scanW(LPCWSTR buf, WCHAR token, DWORD len)
{
    DWORD i;
    for (i = 0; i < len; i++)
        if (buf[i] == token)
            return &buf[i];
    return NULL;
}

/* break out helper functions for deformating */
static LPWSTR deformat_component(MSIPACKAGE* package, LPCWSTR key, DWORD* sz)
{
    LPWSTR value = NULL;
    MSICOMPONENT *comp;
    BOOL source;

    *sz = 0;
    if (!package)
        return NULL;

    comp = get_loaded_component(package,key);
    if (comp)
    {
        source = (comp->Action == INSTALLSTATE_SOURCE) ? TRUE : FALSE;
        value = resolve_folder(package, comp->Directory, source, FALSE, TRUE, NULL);
        *sz = (strlenW(value)) * sizeof(WCHAR);
    }

    return value;
}

static LPWSTR deformat_file(MSIPACKAGE* package, LPCWSTR key, DWORD* sz, 
                            BOOL shortname)
{
    LPWSTR value = NULL;
    MSIFILE *file;

    *sz = 0;

    if (!package)
        return NULL;

    file = get_loaded_file( package, key );
    if (file)
    {
        if (!shortname)
        {
            value = strdupW( file->TargetPath );
            *sz = (strlenW(value)) * sizeof(WCHAR);
        }
        else
        {
            DWORD size = 0;
            size = GetShortPathNameW( file->TargetPath, NULL, 0 );

            if (size > 0)
            {
                *sz = (size-1) * sizeof (WCHAR);
                size ++;
                value = msi_alloc(size * sizeof(WCHAR));
                GetShortPathNameW( file->TargetPath, value, size );
            }
            else
            {
                value = strdupW( file->TargetPath );
                *sz = (lstrlenW(value)) * sizeof(WCHAR);
            }
        }
    }

    return value;
}

static LPWSTR deformat_environment(MSIPACKAGE* package, LPCWSTR key, 
                                   DWORD* chunk)
{
    LPWSTR value = NULL;
    DWORD sz;

    sz  = GetEnvironmentVariableW(key,NULL,0);
    if (sz > 0)
    {
        sz++;
        value = msi_alloc(sz * sizeof(WCHAR));
        GetEnvironmentVariableW(key,value,sz);
        *chunk = (strlenW(value)) * sizeof(WCHAR);
    }
    else
    {
        WARN("Unknown environment variable %s\n", debugstr_w(key));
        *chunk = 0;
        value = NULL;
    }
    return value;
}

 
static LPWSTR deformat_NULL(DWORD* chunk)
{
    LPWSTR value;

    value = msi_alloc(sizeof(WCHAR)*2);
    value[0] =  0;
    *chunk = sizeof(WCHAR);
    return value;
}

static LPWSTR deformat_escape(LPCWSTR key, DWORD* chunk)
{
    LPWSTR value;

    value = msi_alloc(sizeof(WCHAR)*2);
    value[0] =  key[0];
    *chunk = sizeof(WCHAR);

    return value;
}


static BOOL is_key_number(LPCWSTR key)
{
    INT index = 0;
    if (key[0] == 0)
        return FALSE;

    while (isdigitW(key[index])) index++;
    if (key[index] == 0)
        return TRUE;
    else
        return FALSE;
}

static LPWSTR deformat_index(MSIRECORD* record, LPCWSTR key, DWORD* chunk )
{
    INT index;
    LPWSTR value; 

    index = atoiW(key);
    TRACE("record index %i\n",index);
    value = msi_dup_record_field(record,index);
    if (value)
        *chunk = strlenW(value) * sizeof(WCHAR);
    else
    {
        value = NULL;
        *chunk = 0;
    }
    return value;
}

static LPWSTR deformat_property(MSIPACKAGE* package, LPCWSTR key, DWORD* chunk)
{
    LPWSTR value;

    if (!package)
        return NULL;

    value = msi_dup_property( package, key );

    if (value)
        *chunk = (strlenW(value)) * sizeof(WCHAR);

    return value;
}

/*
 * Groups cannot be nested. They are just treated as from { to next } 
 */
static BOOL find_next_group(LPCWSTR source, DWORD len_remaining,
                                    LPWSTR *group, LPCWSTR *mark, 
                                    LPCWSTR* mark2)
{
    int i;
    BOOL found = FALSE;

    *mark = scanW(source,'{',len_remaining);
    if (!*mark)
        return FALSE;

    for (i = 1; (*mark - source) + i < len_remaining; i++)
    {
        if ((*mark)[i] == '}')
        {
            found = TRUE;
            break;
        }
    }
    if (! found)
        return FALSE;

    *mark2 = &(*mark)[i]; 

    i = *mark2 - *mark;
    *group = msi_alloc(i*sizeof(WCHAR));

    i -= 1;
    memcpy(*group,&(*mark)[1],i*sizeof(WCHAR));
    (*group)[i] = 0;

    TRACE("Found group %s\n",debugstr_w(*group));
    return TRUE;
}


static BOOL find_next_outermost_key(LPCWSTR source, DWORD len_remaining,
                                    LPWSTR *key, LPCWSTR *mark, LPCWSTR* mark2, 
                                    BOOL *nested)
{
    INT count = 0;
    INT total_count = 0;
    int i;

    *nested = FALSE;
    *mark = scanW(source,'[',len_remaining);
    if (!*mark)
        return FALSE;

    count = 1;
    total_count = 1;
    for (i = 1; (*mark - source) + i < len_remaining && count > 0; i++)
    {
        if ((*mark)[i] == '[' && (*mark)[i-1] != '\\')
        {
            count ++;
            total_count ++;
            *nested = TRUE;
        }
        else if ((*mark)[i] == ']' && (*mark)[i-1] != '\\')
        {
            count --;
        }
    }

    if (count > 0)
        return FALSE;

    *mark2 = &(*mark)[i-1]; 

    i = *mark2 - *mark;
    *key = msi_alloc(i*sizeof(WCHAR));
    /* do not have the [] in the key */
    i -= 1;
    memcpy(*key,&(*mark)[1],i*sizeof(WCHAR));
    (*key)[i] = 0;

    TRACE("Found Key %s\n",debugstr_w(*key));
    return TRUE;
}

static LPWSTR deformat_group(MSIPACKAGE* package, LPWSTR group, DWORD len, 
                      MSIRECORD* record, DWORD* size)
{
    LPWSTR value = NULL;
    LPCWSTR mark, mark2;
    LPWSTR key;
    BOOL nested;
    INT failcount;
    static const WCHAR fmt[] = {'{','%','s','}',0};
    UINT sz;

    if (!group || group[0] == 0) 
    {
        *size = 0;
        return NULL;
    }
    /* if no [] then group is returned as is */

     if (!find_next_outermost_key(group, len, &key, &mark, &mark2, &nested))
     {
         *size = (len+2)*sizeof(WCHAR);
         value = msi_alloc(*size);
         sprintfW(value,fmt,group);
         /* do not return size of the null at the end */
         *size = (len+1)*sizeof(WCHAR);
         return value;
     }

     msi_free(key);
     failcount = 0;
     sz = deformat_string_internal(package, group, &value, strlenW(group),
                                     record, &failcount);
     if (failcount==0)
     {
        *size = sz * sizeof(WCHAR);
        return value;
     }
     else if (failcount < 0)
     {
         LPWSTR v2;

         v2 = msi_alloc((sz+2)*sizeof(WCHAR));
         v2[0] = '{';
         memcpy(&v2[1],value,sz*sizeof(WCHAR));
         v2[sz+1]='}';
         msi_free(value);

         *size = (sz+2)*sizeof(WCHAR);
         return v2;
     }
     else
     {
         msi_free(value);
         *size = 0;
         return NULL;
     }
}


/*
 * len is in WCHARs
 * return is also in WCHARs
 */
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, 
                                     WCHAR** data, DWORD len, MSIRECORD* record,
                                     INT* failcount)
{
    LPCWSTR mark = NULL;
    LPCWSTR mark2 = NULL;
    DWORD size=0;
    DWORD chunk=0;
    LPWSTR key;
    LPWSTR value = NULL;
    DWORD sz;
    LPBYTE newdata = NULL;
    const WCHAR* progress = NULL;
    BOOL nested = FALSE;

    if (ptr==NULL)
    {
        TRACE("Deformatting NULL string\n");
        *data = NULL;
        return 0;
    }

    TRACE("Starting with %s\n",debugstr_wn(ptr,len));

    /* scan for special characters... fast exit */
    if ((!scanW(ptr,'[',len) || (scanW(ptr,'[',len) && !scanW(ptr,']',len))) && 
        (scanW(ptr,'{',len) && !scanW(ptr,'}',len)))
    {
        /* not formatted */
        *data = msi_alloc((len*sizeof(WCHAR)));
        memcpy(*data,ptr,len*sizeof(WCHAR));
        TRACE("Returning %s\n",debugstr_wn(*data,len));
        return len;
    }
  
    progress = ptr;

    while (progress - ptr < len)
    {
        /* seek out first group if existing */
        if (find_next_group(progress, len - (progress - ptr), &key,
                                &mark, &mark2))
        {
            value = deformat_group(package, key, strlenW(key)+1, record, 
                            &chunk);
            msi_free( key );
            key = NULL;
            nested = FALSE;
        }
        /* formatted string located */
        else if (!find_next_outermost_key(progress, len - (progress - ptr), 
                                &key, &mark, &mark2, &nested))
        {
            LPBYTE nd2;

            TRACE("after value %s\n", debugstr_wn((LPWSTR)newdata,
                                    size/sizeof(WCHAR)));
            chunk = (len - (progress - ptr)) * sizeof(WCHAR);
            TRACE("after chunk is %i + %i\n",size,chunk);
            if (size)
                nd2 = msi_realloc(newdata,(size+chunk));
            else
                nd2 = msi_alloc(chunk);

            newdata = nd2;
            memcpy(&newdata[size],progress,chunk);
            size+=chunk;
            break;
        }

        if (mark != progress)
        {
            LPBYTE tgt;
            DWORD old_size = size;
            INT cnt = (mark - progress);
            TRACE("%i  (%i) characters before marker\n",cnt,(mark-progress));
            size += cnt * sizeof(WCHAR);
            if (!old_size)
                tgt = msi_alloc(size);
            else
                tgt = msi_realloc(newdata,size);
            newdata  = tgt;
            memcpy(&newdata[old_size],progress,(cnt * sizeof(WCHAR)));  
        }

        progress = mark;

        if (nested)
        {
            TRACE("Nested key... %s\n",debugstr_w(key));
            deformat_string_internal(package, key, &value, strlenW(key)+1,
                                     record, failcount);

            msi_free(key);
            key = value;
        }

        TRACE("Current %s .. %s\n",debugstr_wn((LPWSTR)newdata, 
                                size/sizeof(WCHAR)),debugstr_w(key));

        if (!package)
        {
            /* only deformat number indexs */
            if (key && is_key_number(key))
            {
                value = deformat_index(record,key,&chunk);  
                if (!chunk && failcount && *failcount >= 0)
                    (*failcount)++;
            }
            else
            {
                if (failcount)
                    *failcount = -1;
                if(key)
                {
                    DWORD keylen = strlenW(key);
                    chunk = (keylen + 2)*sizeof(WCHAR);
                    value = msi_alloc(chunk);
                    value[0] = '[';
                    memcpy(&value[1],key,keylen*sizeof(WCHAR));
                    value[1+keylen] = ']';
                }
            }
        }
        else
        {
            sz = 0;
            if (key) switch (key[0])
            {
                case '~':
                    value = deformat_NULL(&chunk);
                break;
                case '$':
                    value = deformat_component(package,&key[1],&chunk);
                break;
                case '#':
                    value = deformat_file(package,&key[1], &chunk, FALSE);
                break;
                case '!': /* should be short path */
                    value = deformat_file(package,&key[1], &chunk, TRUE);
                break;
                case '\\':
                    value = deformat_escape(&key[1],&chunk);
                break;
                case '%':
                    value = deformat_environment(package,&key[1],&chunk);
                break;
                default:
                    /* index keys cannot be nested */
                    if (is_key_number(key))
                        if (!nested)
                            value = deformat_index(record,key,&chunk);
                        else
                        {
                            static const WCHAR fmt[] = {'[','%','s',']',0};
                            value = msi_alloc(10);
                            sprintfW(value,fmt,key);
                            chunk = strlenW(value)*sizeof(WCHAR);
                        }
                    else
                        value = deformat_property(package,key,&chunk);
                break;      
            }
        }

        msi_free(key);

        if (value!=NULL)
        {
            LPBYTE nd2;
            TRACE("value %s, chunk %i size %i\n",debugstr_w((LPWSTR)value),
                    chunk, size);
            if (size)
                nd2= msi_realloc(newdata,(size + chunk));
            else
                nd2= msi_alloc(chunk);
            newdata = nd2;
            memcpy(&newdata[size],value,chunk);
            size+=chunk;   
            msi_free(value);
        }
        else if (failcount && *failcount >=0 )
            (*failcount)++;

        progress = mark2+1;
    }

    TRACE("after everything %s\n",debugstr_wn((LPWSTR)newdata, 
                            size/sizeof(WCHAR)));

    *data = (LPWSTR)newdata;
    return size / sizeof(WCHAR);
}


UINT MSI_FormatRecordW( MSIPACKAGE* package, MSIRECORD* record, LPWSTR buffer,
                        LPDWORD size )
{
    LPWSTR deformated;
    LPWSTR rec;
    DWORD len;
    UINT rc = ERROR_INVALID_PARAMETER;

    TRACE("%p %p %p %i\n", package, record ,buffer, *size);

    rec = msi_dup_record_field(record,0);
    if (!rec)
        rec = build_default_format(record);

    TRACE("(%s)\n",debugstr_w(rec));

    len = deformat_string_internal(package,rec,&deformated,
                                   rec ? strlenW(rec) : 0, record, NULL);

    if (buffer)
    {
        if (*size>len)
        {
            memcpy(buffer,deformated,len*sizeof(WCHAR));
            rc = ERROR_SUCCESS;
            buffer[len] = 0;
        }
        else
        {
            if (*size > 0)
            {
                memcpy(buffer,deformated,(*size)*sizeof(WCHAR));
                buffer[(*size)-1] = 0;
            }
            rc = ERROR_MORE_DATA;
        }
    }
    else
        rc = ERROR_SUCCESS;

    *size = len;

    msi_free(rec);
    msi_free(deformated);
    return rc;
}

UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, 
                              LPWSTR szResult, LPDWORD sz )
{
    UINT r = ERROR_INVALID_HANDLE;
    MSIPACKAGE *package;
    MSIRECORD *record;

    TRACE("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);

    package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
    if (!package)
    {
        HRESULT hr;
        IWineMsiRemotePackage *remote_package;
        BSTR value = NULL;
        DWORD len;
        awstring wstr;

        remote_package = (IWineMsiRemotePackage *)msi_get_remote( hInstall );
        if (remote_package)
        {
            len = 0;
            hr = IWineMsiRemotePackage_FormatRecord( remote_package, hRecord,
                                                     NULL, &len );
            if (FAILED(hr))
                goto done;

            len++;
            value = SysAllocStringLen( NULL, len );
            if (!value)
            {
                r = ERROR_OUTOFMEMORY;
                goto done;
            }

            hr = IWineMsiRemotePackage_FormatRecord( remote_package, hRecord,
                                                     value, &len );
            if (FAILED(hr))
                goto done;

            wstr.unicode = TRUE;
            wstr.str.w = szResult;
            r = msi_strcpy_to_awstring( value, &wstr, sz );

done:
            IWineMsiRemotePackage_Release( remote_package );
            SysFreeString( value );

            if (FAILED(hr))
            {
                if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
                    return HRESULT_CODE(hr);

                return ERROR_FUNCTION_FAILED;
            }

            return r;
        }
    }

    record = msihandle2msiinfo( hRecord, MSIHANDLETYPE_RECORD );

    if (!record)
        return ERROR_INVALID_HANDLE;
    if (!sz)
    {
        msiobj_release( &record->hdr );
        if (szResult)
            return ERROR_INVALID_PARAMETER;
        else
            return ERROR_SUCCESS;
    }

    r = MSI_FormatRecordW( package, record, szResult, sz );
    msiobj_release( &record->hdr );
    if (package)
        msiobj_release( &package->hdr );
    return r;
}

UINT WINAPI MsiFormatRecordA( MSIHANDLE hInstall, MSIHANDLE hRecord,
                              LPSTR szResult, LPDWORD sz )
{
    UINT r;
    DWORD len, save;
    LPWSTR value;

    TRACE("%ld %ld %p %p\n", hInstall, hRecord, szResult, sz);

    if (!hRecord)
        return ERROR_INVALID_HANDLE;

    if (!sz)
    {
        if (szResult)
            return ERROR_INVALID_PARAMETER;
        else
            return ERROR_SUCCESS;
    }

    r = MsiFormatRecordW( hInstall, hRecord, NULL, &len );
    if (r != ERROR_SUCCESS)
        return r;

    value = msi_alloc(++len * sizeof(WCHAR));
    if (!value)
        return ERROR_OUTOFMEMORY;

    r = MsiFormatRecordW( hInstall, hRecord, value, &len );
    if (r != ERROR_SUCCESS)
        goto done;

    save = len + 1;
    len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
    WideCharToMultiByte(CP_ACP, 0, value, -1, szResult, *sz, NULL, NULL);

    if (szResult && len > *sz)
    {
        if (*sz) szResult[*sz - 1] = '\0';
        r = ERROR_MORE_DATA;
    }

    *sz = save - 1;

done:
    msi_free(value);
    return r;
}
