/*
 * Implementation of the Microsoft Installer (msi.dll)
 *
 * 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
 */

/*
 * Here are helper functions formally in action.c that are used by a variety of
 * actions and functions.
 */

#include <stdarg.h>

#include "windef.h"
#include "wine/debug.h"
#include "msipriv.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "msidefs.h"

WINE_DEFAULT_DEBUG_CHANNEL(msi);

static const WCHAR cszTargetDir[] = {'T','A','R','G','E','T','D','I','R',0};
static const WCHAR cszDatabase[]={'D','A','T','A','B','A','S','E',0};

LPWSTR build_icon_path(MSIPACKAGE *package, LPCWSTR icon_name )
{
    LPWSTR SystemFolder, dest, FilePath;

    static const WCHAR szInstaller[] = 
        {'M','i','c','r','o','s','o','f','t','\\',
         'I','n','s','t','a','l','l','e','r','\\',0};
    static const WCHAR szFolder[] =
        {'A','p','p','D','a','t','a','F','o','l','d','e','r',0};

    SystemFolder = msi_dup_property( package, szFolder );

    dest = build_directory_name(3, SystemFolder, szInstaller, package->ProductCode);

    create_full_pathW(dest);

    FilePath = build_directory_name(2, dest, icon_name);

    msi_free(SystemFolder);
    msi_free(dest);
    return FilePath;
}

LPWSTR msi_dup_record_field( MSIRECORD *rec, INT field )
{
    DWORD sz = 0;
    LPWSTR str;
    UINT r;

    if (MSI_RecordIsNull( rec, field ))
        return NULL;

    r = MSI_RecordGetStringW( rec, field, NULL, &sz );
    if (r != ERROR_SUCCESS)
        return NULL;

    sz ++;
    str = msi_alloc( sz * sizeof (WCHAR) );
    if (!str)
        return str;
    str[0] = 0;
    r = MSI_RecordGetStringW( rec, field, str, &sz );
    if (r != ERROR_SUCCESS)
    {
        ERR("failed to get string!\n");
        msi_free( str );
        return NULL;
    }
    return str;
}

MSICOMPONENT* get_loaded_component( MSIPACKAGE* package, LPCWSTR Component )
{
    MSICOMPONENT *comp;

    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
    {
        if (lstrcmpW(Component,comp->Component)==0)
            return comp;
    }
    return NULL;
}

MSIFEATURE* get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
{
    MSIFEATURE *feature;

    LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
    {
        if (lstrcmpW( Feature, feature->Feature )==0)
            return feature;
    }
    return NULL;
}

MSIFILE* get_loaded_file( MSIPACKAGE* package, LPCWSTR key )
{
    MSIFILE *file;

    LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
    {
        if (lstrcmpW( key, file->File )==0)
            return file;
    }
    return NULL;
}

int track_tempfile( MSIPACKAGE *package, LPCWSTR path )
{
    MSITEMPFILE *temp;

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

    LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
        if (!lstrcmpW( path, temp->Path ))
            return 0;

    temp = msi_alloc_zero( sizeof (MSITEMPFILE) );
    if (!temp)
        return -1;

    list_add_head( &package->tempfiles, &temp->entry );
    temp->Path = strdupW( path );

    return 0;
}

MSIFOLDER *get_loaded_folder( MSIPACKAGE *package, LPCWSTR dir )
{
    MSIFOLDER *folder;

    LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
    {
        if (lstrcmpW( dir, folder->Directory )==0)
            return folder;
    }
    return NULL;
}

void msi_reset_folders( MSIPACKAGE *package, BOOL source )
{
    MSIFOLDER *folder;

    LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
    {
        if ( source )
        {
            msi_free( folder->ResolvedSource );
            folder->ResolvedSource = NULL;
        }
        else
        {
            msi_free( folder->ResolvedTarget );
            folder->ResolvedTarget = NULL;
        }
    }
}

static LPWSTR get_source_root( MSIPACKAGE *package )
{
    LPWSTR path, p;

    path = msi_dup_property( package, cszSourceDir );
    if (path)
        return path;

    path = msi_dup_property( package, cszDatabase );
    if (path)
    {
        p = strrchrW(path,'\\');
        if (p)
            *(p+1) = 0;
    }
    return path;
}

/*
 * clean_spaces_from_path()
 *
 * removes spaces from the beginning and end of path segments
 * removes multiple \\ characters
 */
static void clean_spaces_from_path( LPWSTR p )
{
    LPWSTR q = p;
    int n, len = 0;

    while (1)
    {
        /* copy until the end of the string or a space */
        while (*p != ' ' && (*q = *p))
        {
            p++, len++;
            /* reduce many backslashes to one */
            if (*p != '\\' || *q != '\\')
                q++;
        }

        /* quit at the end of the string */
        if (!*p)
            break;

        /* count the number of spaces */
        n = 0;
        while (p[n] == ' ')
            n++;

        /* if it's leading or trailing space, skip it */
        if ( len == 0 || p[-1] == '\\' || p[n] == '\\' )
            p += n;
        else  /* copy n spaces */
            while (n && (*q++ = *p++)) n--;
    }
}

LPWSTR resolve_file_source(MSIPACKAGE *package, MSIFILE *file)
{
    LPWSTR p, path;

    TRACE("Working to resolve source of file %s\n", debugstr_w(file->File));

    if (file->IsCompressed)
        return NULL;

    p = resolve_folder(package, file->Component->Directory,
                       TRUE, FALSE, TRUE, NULL);
    path = build_directory_name(2, p, file->ShortName);

    if (file->LongName &&
        GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
    {
        msi_free(path);
        path = build_directory_name(2, p, file->LongName);
    }

    msi_free(p);

    TRACE("file %s source resolves to %s\n", debugstr_w(file->File),
          debugstr_w(path));

    return path;
}

LPWSTR resolve_folder(MSIPACKAGE *package, LPCWSTR name, BOOL source, 
                      BOOL set_prop, BOOL load_prop, MSIFOLDER **folder)
{
    MSIFOLDER *f;
    LPWSTR p, path = NULL, parent;

    TRACE("Working to resolve %s\n",debugstr_w(name));

    if (!name)
        return NULL;

    if (!lstrcmpW(name,cszSourceDir))
        name = cszTargetDir;

    f = get_loaded_folder( package, name );
    if (!f)
        return NULL;

    /* special resolving for Target and Source root dir */
    if (!strcmpW(name,cszTargetDir))
    {
        if (!f->ResolvedTarget && !f->Property)
        {
            LPWSTR check_path;
            check_path = msi_dup_property( package, cszTargetDir );
            if (!check_path)
            {
                check_path = msi_dup_property( package, cszRootDrive );
                if (set_prop)
                    MSI_SetPropertyW(package,cszTargetDir,check_path);
            }

            /* correct misbuilt target dir */
            path = build_directory_name(2, check_path, NULL);
            clean_spaces_from_path( path );
            if (strcmpiW(path,check_path)!=0)
                MSI_SetPropertyW(package,cszTargetDir,path);
            msi_free(check_path);

            f->ResolvedTarget = path;
        }

        if (!f->ResolvedSource)
            f->ResolvedSource = get_source_root( package );
    }

    if (folder)
        *folder = f;

    if (!source && f->ResolvedTarget)
    {
        path = strdupW( f->ResolvedTarget );
        TRACE("   already resolved to %s\n",debugstr_w(path));
        return path;
    }

    if (source && f->ResolvedSource)
    {
        path = strdupW( f->ResolvedSource );
        TRACE("   (source)already resolved to %s\n",debugstr_w(path));
        return path;
    }

    if (!source && f->Property)
    {
        path = build_directory_name( 2, f->Property, NULL );

        TRACE("   internally set to %s\n",debugstr_w(path));
        if (set_prop)
            MSI_SetPropertyW( package, name, path );
        return path;
    }

    if (!source && load_prop && (path = msi_dup_property( package, name )))
    {
        f->ResolvedTarget = strdupW( path );
        TRACE("   property set to %s\n", debugstr_w(path));
        return path;
    }

    if (!f->Parent)
        return path;

    parent = f->Parent;

    TRACE(" ! Parent is %s\n", debugstr_w(parent));

    p = resolve_folder(package, parent, source, set_prop, load_prop, NULL);
    if (!source)
    {
        TRACE("   TargetDefault = %s\n", debugstr_w(f->TargetDefault));

        path = build_directory_name( 3, p, f->TargetDefault, NULL );
        clean_spaces_from_path( path );
        f->ResolvedTarget = strdupW( path );
        TRACE("target -> %s\n", debugstr_w(path));
        if (set_prop)
            MSI_SetPropertyW(package,name,path);
    }
    else
    {
        path = NULL;

        if (package->WordCount & msidbSumInfoSourceTypeCompressed)
            path = get_source_root( package );
        else if (package->WordCount & msidbSumInfoSourceTypeSFN)
            path = build_directory_name( 3, p, f->SourceShortPath, NULL );
        else
            path = build_directory_name( 3, p, f->SourceLongPath, NULL );

        TRACE("source -> %s\n", debugstr_w(path));
        f->ResolvedSource = strdupW( path );
    }
    msi_free(p);

    return path;
}

/* wrapper to resist a need for a full rewrite right now */
DWORD deformat_string(MSIPACKAGE *package, LPCWSTR ptr, WCHAR** data )
{
    if (ptr)
    {
        MSIRECORD *rec = MSI_CreateRecord(1);
        DWORD size = 0;

        MSI_RecordSetStringW(rec,0,ptr);
        MSI_FormatRecordW(package,rec,NULL,&size);

        size++;
        *data = msi_alloc(size*sizeof(WCHAR));
        if (size > 1)
            MSI_FormatRecordW(package,rec,*data,&size);
        else
            *data[0] = 0;

        msiobj_release( &rec->hdr );
        return sizeof(WCHAR)*size;
    }

    *data = NULL;
    return 0;
}

UINT schedule_action(MSIPACKAGE *package, UINT script, LPCWSTR action)
{
    UINT count;
    LPWSTR *newbuf = NULL;
    if (script >= TOTAL_SCRIPTS)
    {
        FIXME("Unknown script requested %i\n",script);
        return ERROR_FUNCTION_FAILED;
    }
    TRACE("Scheduling Action %s in script %i\n",debugstr_w(action), script);
    
    count = package->script->ActionCount[script];
    package->script->ActionCount[script]++;
    if (count != 0)
        newbuf = msi_realloc( package->script->Actions[script],
                        package->script->ActionCount[script]* sizeof(LPWSTR));
    else
        newbuf = msi_alloc( sizeof(LPWSTR));

    newbuf[count] = strdupW(action);
    package->script->Actions[script] = newbuf;

   return ERROR_SUCCESS;
}

void msi_free_action_script(MSIPACKAGE *package, UINT script)
{
    UINT i;
    for (i = 0; i < package->script->ActionCount[script]; i++)
        msi_free(package->script->Actions[script][i]);

    msi_free(package->script->Actions[script]);
    package->script->Actions[script] = NULL;
    package->script->ActionCount[script] = 0;
}

/*
 *  build_directory_name()
 *
 *  This function is to save messing round with directory names
 *  It handles adding backslashes between path segments, 
 *   and can add \ at the end of the directory name if told to.
 *
 *  It takes a variable number of arguments.
 *  It always allocates a new string for the result, so make sure
 *   to free the return value when finished with it.
 *
 *  The first arg is the number of path segments that follow.
 *  The arguments following count are a list of path segments.
 *  A path segment may be NULL.
 *
 *  Path segments will be added with a \ separating them.
 *  A \ will not be added after the last segment, however if the
 *    last segment is NULL, then the last character will be a \
 * 
 */
LPWSTR build_directory_name(DWORD count, ...)
{
    DWORD sz = 1, i;
    LPWSTR dir;
    va_list va;

    va_start(va,count);
    for(i=0; i<count; i++)
    {
        LPCWSTR str = va_arg(va,LPCWSTR);
        if (str)
            sz += strlenW(str) + 1;
    }
    va_end(va);

    dir = msi_alloc(sz*sizeof(WCHAR));
    dir[0]=0;

    va_start(va,count);
    for(i=0; i<count; i++)
    {
        LPCWSTR str = va_arg(va,LPCWSTR);
        if (!str)
            continue;
        strcatW(dir, str);
        if( ((i+1)!=count) && dir[strlenW(dir)-1]!='\\')
            strcatW(dir, szBackSlash);
    }
    return dir;
}

/***********************************************************************
 *            create_full_pathW
 *
 * Recursively create all directories in the path.
 *
 * shamelessly stolen from setupapi/queue.c
 */
BOOL create_full_pathW(const WCHAR *path)
{
    BOOL ret = TRUE;
    int len;
    WCHAR *new_path;

    new_path = msi_alloc( (strlenW(path) + 1) * sizeof(WCHAR));

    strcpyW(new_path, path);

    while((len = strlenW(new_path)) && new_path[len - 1] == '\\')
    new_path[len - 1] = 0;

    while(!CreateDirectoryW(new_path, NULL))
    {
        WCHAR *slash;
        DWORD last_error = GetLastError();
        if(last_error == ERROR_ALREADY_EXISTS)
            break;

        if(last_error != ERROR_PATH_NOT_FOUND)
        {
            ret = FALSE;
            break;
        }

        if(!(slash = strrchrW(new_path, '\\')))
        {
            ret = FALSE;
            break;
        }

        len = slash - new_path;
        new_path[len] = 0;
        if(!create_full_pathW(new_path))
        {
            ret = FALSE;
            break;
        }
        new_path[len] = '\\';
    }

    msi_free(new_path);
    return ret;
}

void ui_progress(MSIPACKAGE *package, int a, int b, int c, int d )
{
    MSIRECORD * row;

    row = MSI_CreateRecord(4);
    MSI_RecordSetInteger(row,1,a);
    MSI_RecordSetInteger(row,2,b);
    MSI_RecordSetInteger(row,3,c);
    MSI_RecordSetInteger(row,4,d);
    MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
    msiobj_release(&row->hdr);

    msi_dialog_check_messages(NULL);
}

void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * record)
{
    static const WCHAR Query_t[] = 
        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
         '`','A','c','t','i','o', 'n','T','e','x','t','`',' ',
         'W','H','E','R','E',' ', '`','A','c','t','i','o','n','`',' ','=', 
         ' ','\'','%','s','\'',0};
    WCHAR message[1024];
    MSIRECORD * row = 0;
    DWORD size;

    if (!package->LastAction || strcmpW(package->LastAction,action))
    {
        row = MSI_QueryGetRecord(package->db, Query_t, action);
        if (!row)
            return;

        if (MSI_RecordIsNull(row,3))
        {
            msiobj_release(&row->hdr);
            return;
        }

        /* update the cached actionformat */
        msi_free(package->ActionFormat);
        package->ActionFormat = msi_dup_record_field(row,3);

        msi_free(package->LastAction);
        package->LastAction = strdupW(action);

        msiobj_release(&row->hdr);
    }

    MSI_RecordSetStringW(record,0,package->ActionFormat);
    size = 1024;
    MSI_FormatRecordW(package,record,message,&size);

    row = MSI_CreateRecord(1);
    MSI_RecordSetStringW(row,1,message);
 
    MSI_ProcessMessage(package, INSTALLMESSAGE_ACTIONDATA, row);

    msiobj_release(&row->hdr);
}

void reduce_to_longfilename(WCHAR* filename)
{
    LPWSTR p = strchrW(filename,'|');
    if (p)
        memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
}

LPWSTR create_component_advertise_string(MSIPACKAGE* package, 
                MSICOMPONENT* component, LPCWSTR feature)
{
    static const WCHAR fmt[] = {'%','s','%','s','%','c','%','s',0};
    WCHAR productid_85[21], component_85[21];
    LPWSTR output = NULL;
    DWORD sz = 0;
    GUID clsid;

    /* > is used if there is a component GUID and < if not.  */

    productid_85[0] = 0;
    component_85[0] = 0;

    CLSIDFromString(package->ProductCode, &clsid);
    encode_base85_guid(&clsid, productid_85);

    if (component)
    {
        CLSIDFromString(component->ComponentId, &clsid);
        encode_base85_guid(&clsid, component_85);
    }

    TRACE("prod=%s feat=%s comp=%s\n", debugstr_w(productid_85),
          debugstr_w(feature), debugstr_w(component_85));
 
    sz = 20 + lstrlenW(feature) + 20 + 3;

    output = msi_alloc_zero(sz*sizeof(WCHAR));

    sprintfW(output, fmt, productid_85, feature,
             component?'>':'<', component_85);
    
    return output;
}

/* update component state based on a feature change */
void ACTION_UpdateComponentStates(MSIPACKAGE *package, LPCWSTR szFeature)
{
    INSTALLSTATE newstate;
    MSIFEATURE *feature;
    ComponentList *cl;

    feature = get_loaded_feature(package,szFeature);
    if (!feature)
        return;

    newstate = feature->ActionRequest;

    if (newstate == INSTALLSTATE_ABSENT)
        newstate = INSTALLSTATE_UNKNOWN;

    LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
    {
        MSICOMPONENT* component = cl->component;
    
        TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n",
            newstate, debugstr_w(component->Component), component->Installed, 
            component->Action, component->ActionRequest);
        
        if (!component->Enabled)
            continue;
 
        if (newstate == INSTALLSTATE_LOCAL)
            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
        else 
        {
            ComponentList *clist;
            MSIFEATURE *f;

            component->hasLocalFeature = FALSE;

            msi_component_set_state(package, component, newstate);

            /*if any other feature wants is local we need to set it local*/
            LIST_FOR_EACH_ENTRY( f, &package->features, MSIFEATURE, entry )
            {
                if ( f->ActionRequest != INSTALLSTATE_LOCAL &&
                     f->ActionRequest != INSTALLSTATE_SOURCE )
                {
                    continue;
                }

                LIST_FOR_EACH_ENTRY( clist, &f->Components, ComponentList, entry )
                {
                    if ( clist->component == component &&
                         (f->ActionRequest == INSTALLSTATE_LOCAL ||
                          f->ActionRequest == INSTALLSTATE_SOURCE) )
                    {
                        TRACE("Saved by %s\n", debugstr_w(f->Feature));
                        component->hasLocalFeature = TRUE;

                        if (component->Attributes & msidbComponentAttributesOptional)
                        {
                            if (f->Attributes & msidbFeatureAttributesFavorSource)
                                msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
                            else
                                msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
                        }
                        else if (component->Attributes & msidbComponentAttributesSourceOnly)
                            msi_component_set_state(package, component, INSTALLSTATE_SOURCE);
                        else
                            msi_component_set_state(package, component, INSTALLSTATE_LOCAL);
                    }
                }
            }
        }
        TRACE("Result (%i): Component %s (Installed %i, Action %i, Request %i)\n",
            newstate, debugstr_w(component->Component), component->Installed, 
            component->Action, component->ActionRequest);
    } 
}

UINT register_unique_action(MSIPACKAGE *package, LPCWSTR action)
{
    UINT count;
    LPWSTR *newbuf = NULL;

    if (!package->script)
        return FALSE;

    TRACE("Registering Action %s as having fun\n",debugstr_w(action));
    
    count = package->script->UniqueActionsCount;
    package->script->UniqueActionsCount++;
    if (count != 0)
        newbuf = msi_realloc( package->script->UniqueActions,
                        package->script->UniqueActionsCount* sizeof(LPWSTR));
    else
        newbuf = msi_alloc( sizeof(LPWSTR));

    newbuf[count] = strdupW(action);
    package->script->UniqueActions = newbuf;

    return ERROR_SUCCESS;
}

BOOL check_unique_action(const MSIPACKAGE *package, LPCWSTR action)
{
    UINT i;

    if (!package->script)
        return FALSE;

    for (i = 0; i < package->script->UniqueActionsCount; i++)
        if (!strcmpW(package->script->UniqueActions[i],action))
            return TRUE;

    return FALSE;
}

WCHAR* generate_error_string(MSIPACKAGE *package, UINT error, DWORD count, ... )
{
    static const WCHAR query[] = {'S','E','L','E','C','T',' ','`','M','e','s','s','a','g','e','`',' ','F','R','O','M',' ','`','E','r','r','o','r','`',' ','W','H','E','R','E',' ','`','E','r','r','o','r','`',' ','=',' ','%','i',0};

    MSIRECORD *rec;
    MSIRECORD *row;
    DWORD size = 0;
    DWORD i;
    va_list va;
    LPCWSTR str;
    LPWSTR data;

    row = MSI_QueryGetRecord(package->db, query, error);
    if (!row)
        return 0;

    rec = MSI_CreateRecord(count+2);

    str = MSI_RecordGetString(row,1);
    MSI_RecordSetStringW(rec,0,str);
    msiobj_release( &row->hdr );
    MSI_RecordSetInteger(rec,1,error);

    va_start(va,count);
    for (i = 0; i < count; i++)
    {
        str = va_arg(va,LPCWSTR);
        MSI_RecordSetStringW(rec,(i+2),str);
    }
    va_end(va);

    MSI_FormatRecordW(package,rec,NULL,&size);

    size++;
    data = msi_alloc(size*sizeof(WCHAR));
    if (size > 1)
        MSI_FormatRecordW(package,rec,data,&size);
    else
        data[0] = 0;
    msiobj_release( &rec->hdr );
    return data;
}
