/*
 * winemsibuilder - tool to build MSI packages
 *
 * Copyright 2010 Hans Leidekker 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 WIN32_LEAN_AND_MEAN
#define COBJMACROS

#include <stdio.h>
#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#include <objbase.h>

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

WINE_DEFAULT_DEBUG_CHANNEL(winemsibuilder);

static UINT open_database( const WCHAR *msifile, MSIHANDLE *handle )
{
    UINT r;
    MSIHANDLE hdb;

    if (GetFileAttributesW( msifile ) == INVALID_FILE_ATTRIBUTES)
    {
        r = MsiOpenDatabaseW( msifile, MSIDBOPEN_CREATE, &hdb );
        if (r != ERROR_SUCCESS)
        {
            WINE_ERR( "failed to create package database %s (%u)\n", wine_dbgstr_w(msifile), r );
            return r;
        }
        r = MsiDatabaseCommit( hdb );
        if (r != ERROR_SUCCESS)
        {
            WINE_ERR( "failed to commit database (%u)\n", r );
            MsiCloseHandle( hdb );
            return r;
        }
    }
    else
    {
        r = MsiOpenDatabaseW( msifile, MSIDBOPEN_TRANSACT, &hdb );
        if (r != ERROR_SUCCESS)
        {
            WINE_ERR( "failed to open package database %s (%u)\n", wine_dbgstr_w(msifile), r );
            return r;
        }
    }

    *handle = hdb;
    return ERROR_SUCCESS;
}

static int import_tables( const WCHAR *msifile, WCHAR **tables )
{
    UINT r;
    MSIHANDLE hdb;
    WCHAR *dir;
    DWORD len;

    r = open_database( msifile, &hdb );
    if (r != ERROR_SUCCESS) return 1;

    len = GetCurrentDirectoryW( 0, NULL );
    if (!(dir = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
    {
        MsiCloseHandle( hdb );
        return 1;
    }
    GetCurrentDirectoryW( len + 1, dir );

    while (*tables)
    {
        r = MsiDatabaseImportW( hdb, dir, *tables );
        if (r != ERROR_SUCCESS)
        {
            WINE_ERR( "failed to import table %s (%u)\n", wine_dbgstr_w(*tables), r );
            break;
        }
        tables++;
    }

    if (r == ERROR_SUCCESS)
    {
        r = MsiDatabaseCommit( hdb );
        if (r != ERROR_SUCCESS)
            WINE_ERR( "failed to commit changes (%u)\n", r );
    }

    HeapFree( GetProcessHeap(), 0, dir );
    MsiCloseHandle( hdb );
    return (r != ERROR_SUCCESS);
}

/* taken from dlls/msi/table.c */
static int utf2mime( int x )
{
    if (x >= '0' && x <= '9')
        return x - '0';
    if (x >= 'A' && x <= 'Z')
        return x - 'A' + 10;
    if (x >= 'a' && x <= 'z')
        return x - 'a' + 10 + 26;
    if (x == '.')
        return 10 + 26 + 26;
    if (x == '_')
        return 10 + 26 + 26 + 1;
    return -1;
}

#define MAX_STREAM_NAME 0x1f

static WCHAR *encode_stream( const WCHAR *in )
{
    DWORD c, next, count;
    WCHAR *out, *p;

    count = strlenW( in );
    if (count > MAX_STREAM_NAME)
        return NULL;

    count += 2;
    if (!(out = HeapAlloc( GetProcessHeap(), 0, count * sizeof(WCHAR) ))) return NULL;
    p = out;
    while (count--)
    {
        c = *in++;
        if (!c)
        {
            *p = c;
            return out;
        }
        if (c < 0x80 && utf2mime( c ) >= 0)
        {
            c = utf2mime( c ) + 0x4800;
            next = *in;
            if (next && next < 0x80)
            {
                next = utf2mime( next );
                if (next != -1)
                {
                     next += 0x3ffffc0;
                     c += next << 6;
                     in++;
                }
            }
        }
        *p++ = c;
    }
    HeapFree( GetProcessHeap(), 0, out );
    return NULL;
}

static int add_stream( const WCHAR *msifile, const WCHAR *stream, const WCHAR *file )
{
    UINT r;
    HRESULT hr;
    MSIHANDLE hdb;
    IStorage *stg;
    IStream *stm = NULL;
    HANDLE handle;
    char buffer[4096];
    ULARGE_INTEGER size;
    DWORD low, high, read;
    WCHAR *encname;
    int ret = 1;

    /* make sure we have the right type of file  */
    r = open_database( msifile, &hdb );
    if (r != ERROR_SUCCESS) return 1;
    MsiCloseHandle( hdb );

    hr = StgOpenStorage( msifile, NULL, STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg );
    if (hr != S_OK)
    {
        WINE_WARN( "failed to open storage %s (0x%08x)\n", wine_dbgstr_w(msifile), hr );
        return 1;
    }
    encname = encode_stream( stream );
    if (!encname)
    {
        WINE_WARN( "failed to encode stream name %s\n", wine_dbgstr_w(stream) );
        goto done;
    }
    hr = IStorage_CreateStream( stg, encname, STGM_CREATE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, 0, 0, &stm );
    if (hr != S_OK)
    {
        WINE_WARN( "failed to create stream %s (0x%08x)\n", wine_dbgstr_w(encname), hr );
        goto done;
    }
    handle = CreateFileW( file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
    if (handle == INVALID_HANDLE_VALUE)
    {
        WINE_WARN( "failed to open file %s (%u)\n", wine_dbgstr_w(file), GetLastError() );
        goto done;
    }
    low = GetFileSize( handle, &high );
    if (low == INVALID_FILE_SIZE || high)
    {
        WINE_WARN( "file %s too big\n", wine_dbgstr_w(file) );
        CloseHandle( handle );
        goto done;
    }
    size.QuadPart = low;
    hr = IStream_SetSize( stm, size );
    if (hr != S_OK) goto done;

    while (ReadFile( handle, buffer, sizeof(buffer), &read, NULL ) && read)
    {
        hr = IStream_Write( stm, buffer, read, NULL );
        if (hr != S_OK) break;
        size.QuadPart -= read;
    }
    CloseHandle( handle );
    if (size.QuadPart)
    {
        WINE_WARN( "failed to write stream contents\n" );
        goto done;
    }
    IStorage_Commit( stg, 0 );
    ret = 0;

done:
    HeapFree( GetProcessHeap(), 0, encname );
    if (stm) IStream_Release( stm );
    IStorage_Release( stg );
    return ret;
}

static void show_usage( void )
{
    WINE_MESSAGE(
        "Usage: winemsibuilder [OPTION] [MSIFILE] ...\n"
        "Options:\n"
        "  -i package.msi table1.idt [table2.idt ...]    Import one or more tables into the database.\n"
        "  -a package.msi stream file                    Add 'stream' to storage with contents of 'file'.\n"
        "\nExisting tables or streams will be overwritten. If package.msi does not exist a new file\n"
        "will be created with an empty database.\n"
    );
}

int wmain( int argc, WCHAR *argv[] )
{
    if (argc < 3 || argv[1][0] != '-')
    {
        show_usage();
        return 1;
    }

    switch (argv[1][1])
    {
    case 'i':
        if (argc < 4) break;
        return import_tables( argv[2], argv + 3 );
    case 'a':
        if (argc < 5) break;
        return add_stream( argv[2], argv[3], argv[4] );
    default:
        WINE_WARN( "unknown option\n" );
        break;
    }

    show_usage();
    return 1;
}
