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

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
#include "msipriv.h"
#include "query.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(msidb);

#define NUM_STREAMS_COLS    2

typedef struct tabSTREAM
{
    UINT str_index;
    IStream *stream;
} STREAM;

typedef struct tagMSISTREAMSVIEW
{
    MSIVIEW view;
    MSIDATABASE *db;
    STREAM **streams;
    UINT max_streams;
    UINT num_rows;
    UINT row_size;
} MSISTREAMSVIEW;

static BOOL streams_set_table_size(MSISTREAMSVIEW *sv, UINT size)
{
    if (size >= sv->max_streams)
    {
        sv->max_streams *= 2;
        sv->streams = msi_realloc_zero(sv->streams, sv->max_streams * sizeof(STREAM *));
        if (!sv->streams)
            return FALSE;
    }

    return TRUE;
}

static STREAM *create_stream(MSISTREAMSVIEW *sv, LPCWSTR name, BOOL encoded, IStream *stm)
{
    STREAM *stream;
    WCHAR decoded[MAX_STREAM_NAME_LEN];

    stream = msi_alloc(sizeof(STREAM));
    if (!stream)
        return NULL;

    if (encoded)
    {
        decode_streamname(name, decoded);
        TRACE("stream -> %s %s\n", debugstr_w(name), debugstr_w(decoded));
        name = decoded;
    }

    stream->str_index = msi_addstringW(sv->db->strings, name, -1, 1, StringNonPersistent);
    stream->stream = stm;
    return stream;
}

static UINT STREAMS_fetch_int(struct tagMSIVIEW *view, UINT row, UINT col, UINT *val)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;

    TRACE("(%p, %d, %d, %p)\n", view, row, col, val);

    if (col != 1)
        return ERROR_INVALID_PARAMETER;

    if (row >= sv->num_rows)
        return ERROR_NO_MORE_ITEMS;

    *val = sv->streams[row]->str_index;

    return ERROR_SUCCESS;
}

static UINT STREAMS_fetch_stream(struct tagMSIVIEW *view, UINT row, UINT col, IStream **stm)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;

    TRACE("(%p, %d, %d, %p)\n", view, row, col, stm);

    if (row >= sv->num_rows)
        return ERROR_FUNCTION_FAILED;

    IStream_AddRef(sv->streams[row]->stream);
    *stm = sv->streams[row]->stream;

    return ERROR_SUCCESS;
}

static UINT STREAMS_get_row( struct tagMSIVIEW *view, UINT row, MSIRECORD **rec )
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;

    TRACE("%p %d %p\n", sv, row, rec);

    return msi_view_get_row( sv->db, view, row, rec );
}

static UINT STREAMS_set_row(struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UINT mask)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
    STREAM *stream;
    IStream *stm;
    STATSTG stat;
    LPWSTR encname = NULL, name = NULL;
    USHORT *data = NULL;
    HRESULT hr;
    ULONG count;
    UINT r = ERROR_FUNCTION_FAILED;

    TRACE("(%p, %d, %p, %08x)\n", view, row, rec, mask);

    if (row > sv->num_rows)
        return ERROR_FUNCTION_FAILED;

    r = MSI_RecordGetIStream(rec, 2, &stm);
    if (r != ERROR_SUCCESS)
        return r;

    hr = IStream_Stat(stm, &stat, STATFLAG_NONAME);
    if (FAILED(hr))
    {
        WARN("failed to stat stream: %08x\n", hr);
        goto done;
    }

    if (stat.cbSize.QuadPart >> 32)
    {
        WARN("stream too large\n");
        goto done;
    }

    data = msi_alloc(stat.cbSize.QuadPart);
    if (!data)
        goto done;

    hr = IStream_Read(stm, data, stat.cbSize.QuadPart, &count);
    if (FAILED(hr) || count != stat.cbSize.QuadPart)
    {
        WARN("failed to read stream: %08x\n", hr);
        goto done;
    }

    name = strdupW(MSI_RecordGetString(rec, 1));
    if (!name)
    {
        WARN("failed to retrieve stream name\n");
        goto done;
    }

    encname = encode_streamname(FALSE, name);
    msi_destroy_stream(sv->db, encname);

    r = write_stream_data(sv->db->storage, name, data, count, FALSE);
    if (r != ERROR_SUCCESS)
    {
        WARN("failed to write stream data: %d\n", r);
        goto done;
    }

    stream = create_stream(sv, name, FALSE, NULL);
    if (!stream)
        goto done;

    hr = IStorage_OpenStream(sv->db->storage, encname, 0,
                             STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream->stream);
    if (FAILED(hr))
    {
        WARN("failed to open stream: %08x\n", hr);
        msi_free(stream);
        goto done;
    }

    sv->streams[row] = stream;

done:
    msi_free(name);
    msi_free(data);
    msi_free(encname);

    IStream_Release(stm);

    return r;
}

static UINT STREAMS_insert_row(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL temporary)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
    UINT i;

    TRACE("(%p, %p, %d, %d)\n", view, rec, row, temporary);

    if (!streams_set_table_size(sv, ++sv->num_rows))
        return ERROR_FUNCTION_FAILED;

    if (row == -1)
        row = sv->num_rows - 1;

    /* shift the rows to make room for the new row */
    for (i = sv->num_rows - 1; i > row; i--)
    {
        sv->streams[i] = sv->streams[i - 1];
    }

    return STREAMS_set_row(view, row, rec, 0);
}

static UINT STREAMS_delete_row(struct tagMSIVIEW *view, UINT row)
{
    FIXME("(%p %d): stub!\n", view, row);
    return ERROR_SUCCESS;
}

static UINT STREAMS_execute(struct tagMSIVIEW *view, MSIRECORD *record)
{
    TRACE("(%p, %p)\n", view, record);
    return ERROR_SUCCESS;
}

static UINT STREAMS_close(struct tagMSIVIEW *view)
{
    TRACE("(%p)\n", view);
    return ERROR_SUCCESS;
}

static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *cols)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;

    TRACE("(%p, %p, %p)\n", view, rows, cols);

    if (cols) *cols = NUM_STREAMS_COLS;
    if (rows) *rows = sv->num_rows;

    return ERROR_SUCCESS;
}

static UINT STREAMS_get_column_info( struct tagMSIVIEW *view, UINT n, LPCWSTR *name,
                                     UINT *type, BOOL *temporary, LPCWSTR *table_name )
{
    TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
          table_name);

    if (n == 0 || n > NUM_STREAMS_COLS)
        return ERROR_INVALID_PARAMETER;

    switch (n)
    {
    case 1:
        if (name) *name = szName;
        if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MAX_STREAM_NAME_LEN;
        break;

    case 2:
        if (name) *name = szData;
        if (type) *type = MSITYPE_STRING | MSITYPE_VALID | MSITYPE_NULLABLE;
        break;
    }
    if (table_name) *table_name = szStreams;
    if (temporary) *temporary = FALSE;
    return ERROR_SUCCESS;
}

static UINT streams_find_row(MSISTREAMSVIEW *sv, MSIRECORD *rec, UINT *row)
{
    LPCWSTR str;
    UINT r, i, id, data;

    str = MSI_RecordGetString(rec, 1);
    r = msi_string2id(sv->db->strings, str, -1, &id);
    if (r != ERROR_SUCCESS)
        return r;

    for (i = 0; i < sv->num_rows; i++)
    {
        STREAMS_fetch_int(&sv->view, i, 1, &data);

        if (data == id)
        {
            *row = i;
            return ERROR_SUCCESS;
        }
    }

    return ERROR_FUNCTION_FAILED;
}

static UINT streams_modify_update(struct tagMSIVIEW *view, MSIRECORD *rec)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
    UINT r, row;

    r = streams_find_row(sv, rec, &row);
    if (r != ERROR_SUCCESS)
        return ERROR_FUNCTION_FAILED;

    return STREAMS_set_row(view, row, rec, 0);
}

static UINT streams_modify_assign(struct tagMSIVIEW *view, MSIRECORD *rec)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
    UINT r, row;

    r = streams_find_row(sv, rec, &row);
    if (r == ERROR_SUCCESS)
        return streams_modify_update(view, rec);

    return STREAMS_insert_row(view, rec, -1, FALSE);
}

static UINT STREAMS_modify(struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
{
    UINT r;

    TRACE("%p %d %p\n", view, eModifyMode, rec);

    switch (eModifyMode)
    {
    case MSIMODIFY_ASSIGN:
        r = streams_modify_assign(view, rec);
        break;

    case MSIMODIFY_INSERT:
        r = STREAMS_insert_row(view, rec, -1, FALSE);
        break;

    case MSIMODIFY_UPDATE:
        r = streams_modify_update(view, rec);
        break;

    case MSIMODIFY_VALIDATE_NEW:
    case MSIMODIFY_INSERT_TEMPORARY:
    case MSIMODIFY_REFRESH:
    case MSIMODIFY_REPLACE:
    case MSIMODIFY_MERGE:
    case MSIMODIFY_DELETE:
    case MSIMODIFY_VALIDATE:
    case MSIMODIFY_VALIDATE_FIELD:
    case MSIMODIFY_VALIDATE_DELETE:
        FIXME("%p %d %p - mode not implemented\n", view, eModifyMode, rec );
        r = ERROR_CALL_NOT_IMPLEMENTED;
        break;

    default:
        r = ERROR_INVALID_DATA;
    }

    return r;
}

static UINT STREAMS_delete(struct tagMSIVIEW *view)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
    UINT i;

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

    for (i = 0; i < sv->num_rows; i++)
    {
        if (sv->streams[i])
        {
            if (sv->streams[i]->stream)
                IStream_Release(sv->streams[i]->stream);
            msi_free(sv->streams[i]);
        }
    }

    msi_free(sv->streams);
    msi_free(sv);

    return ERROR_SUCCESS;
}

static UINT STREAMS_find_matching_rows(struct tagMSIVIEW *view, UINT col,
                                       UINT val, UINT *row, MSIITERHANDLE *handle)
{
    MSISTREAMSVIEW *sv = (MSISTREAMSVIEW *)view;
    UINT index = PtrToUlong(*handle);

    TRACE("(%p, %d, %d, %p, %p)\n", view, col, val, row, handle);

    if (col == 0 || col > NUM_STREAMS_COLS)
        return ERROR_INVALID_PARAMETER;

    while (index < sv->num_rows)
    {
        if (sv->streams[index]->str_index == val)
        {
            *row = index;
            break;
        }

        index++;
    }

    *handle = UlongToPtr(++index);

    if (index > sv->num_rows)
        return ERROR_NO_MORE_ITEMS;

    return ERROR_SUCCESS;
}

static const MSIVIEWOPS streams_ops =
{
    STREAMS_fetch_int,
    STREAMS_fetch_stream,
    STREAMS_get_row,
    STREAMS_set_row,
    STREAMS_insert_row,
    STREAMS_delete_row,
    STREAMS_execute,
    STREAMS_close,
    STREAMS_get_dimensions,
    STREAMS_get_column_info,
    STREAMS_modify,
    STREAMS_delete,
    STREAMS_find_matching_rows,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

static INT add_streams_to_table(MSISTREAMSVIEW *sv)
{
    IEnumSTATSTG *stgenum = NULL;
    STATSTG stat;
    STREAM *stream = NULL;
    HRESULT hr;
    UINT r, count = 0, size;
    LPWSTR encname;

    hr = IStorage_EnumElements(sv->db->storage, 0, NULL, 0, &stgenum);
    if (FAILED(hr))
        return -1;

    sv->max_streams = 1;
    sv->streams = msi_alloc_zero(sizeof(STREAM *));
    if (!sv->streams)
        return -1;

    while (TRUE)
    {
        size = 0;
        hr = IEnumSTATSTG_Next(stgenum, 1, &stat, &size);
        if (FAILED(hr) || !size)
            break;

        if (stat.type != STGTY_STREAM)
        {
            CoTaskMemFree(stat.pwcsName);
            continue;
        }

        /* table streams are not in the _Streams table */
        if (*stat.pwcsName == 0x4840)
        {
            CoTaskMemFree(stat.pwcsName);
            continue;
        }

        stream = create_stream(sv, stat.pwcsName, TRUE, NULL);
        if (!stream)
        {
            count = -1;
            CoTaskMemFree(stat.pwcsName);
            break;
        }

        /* these streams appear to be unencoded */
        if (*stat.pwcsName == 0x0005)
        {
            r = msi_get_raw_stream(sv->db, stat.pwcsName, &stream->stream);
        }
        else
        {
            encname = encode_streamname(FALSE, stat.pwcsName);
            r = msi_get_raw_stream(sv->db, encname, &stream->stream);
            msi_free(encname);
        }
        CoTaskMemFree(stat.pwcsName);

        if (r != ERROR_SUCCESS)
        {
            WARN("unable to get stream %u\n", r);
            count = -1;
            break;
        }

        if (!streams_set_table_size(sv, ++count))
        {
            count = -1;
            break;
        }

        sv->streams[count - 1] = stream;
    }

    IEnumSTATSTG_Release(stgenum);
    return count;
}

UINT STREAMS_CreateView(MSIDATABASE *db, MSIVIEW **view)
{
    MSISTREAMSVIEW *sv;
    INT rows;

    TRACE("(%p, %p)\n", db, view);

    sv = msi_alloc_zero( sizeof(MSISTREAMSVIEW) );
    if (!sv)
        return ERROR_FUNCTION_FAILED;

    sv->view.ops = &streams_ops;
    sv->db = db;
    rows = add_streams_to_table(sv);
    if (rows < 0)
    {
        msi_free( sv );
        return ERROR_FUNCTION_FAILED;
    }
    sv->num_rows = rows;

    *view = (MSIVIEW *)sv;

    return ERROR_SUCCESS;
}
