/*
 * IAssemblyName implementation
 *
 * Copyright 2012 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
 */

#include <stdarg.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "winsxs.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(sxs);

struct name
{
    IAssemblyName IAssemblyName_iface;
    LONG   refs;
    WCHAR *name;
    WCHAR *arch;
    WCHAR *token;
    WCHAR *type;
    WCHAR *version;
};

static const WCHAR archW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0};
static const WCHAR tokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
static const WCHAR typeW[] = {'t','y','p','e',0};
static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};

static inline struct name *impl_from_IAssemblyName( IAssemblyName *iface )
{
    return CONTAINING_RECORD( iface, struct name, IAssemblyName_iface );
}

static HRESULT WINAPI name_QueryInterface(
    IAssemblyName *iface,
    REFIID riid,
    void **obj )
{
    struct name *name = impl_from_IAssemblyName( iface );

    TRACE("%p, %s, %p\n", name, debugstr_guid(riid), obj);

    *obj = NULL;

    if (IsEqualIID( riid, &IID_IUnknown ) ||
        IsEqualIID( riid, &IID_IAssemblyName ))
    {
        IAssemblyName_AddRef( iface );
        *obj = name;
        return S_OK;
    }

    return E_NOINTERFACE;
}

static ULONG WINAPI name_AddRef(
    IAssemblyName *iface )
{
    struct name *name = impl_from_IAssemblyName( iface );
    return InterlockedIncrement( &name->refs );
}

static ULONG WINAPI name_Release( IAssemblyName *iface )
{
    struct name *name = impl_from_IAssemblyName( iface );
    ULONG refs = InterlockedDecrement( &name->refs );

    if (!refs)
    {
        TRACE("destroying %p\n", name);
        HeapFree( GetProcessHeap(), 0, name->name );
        HeapFree( GetProcessHeap(), 0, name->arch );
        HeapFree( GetProcessHeap(), 0, name->token );
        HeapFree( GetProcessHeap(), 0, name->type );
        HeapFree( GetProcessHeap(), 0, name->version );
        HeapFree( GetProcessHeap(), 0, name );
    }
    return refs;
}

static HRESULT WINAPI name_SetProperty(
    IAssemblyName *iface,
    DWORD id,
    LPVOID property,
    DWORD size )
{
    FIXME("%p, %d, %p, %d\n", iface, id, property, size);
    return E_NOTIMPL;
}

static HRESULT WINAPI name_GetProperty(
    IAssemblyName *iface,
    DWORD id,
    LPVOID buffer,
    LPDWORD buflen )
{
    FIXME("%p, %d, %p, %p\n", iface, id, buffer, buflen);
    return E_NOTIMPL;
}

static HRESULT WINAPI name_Finalize(
    IAssemblyName *iface )
{
    FIXME("%p\n", iface);
    return E_NOTIMPL;
}

static HRESULT WINAPI name_GetDisplayName(
    IAssemblyName *iface,
    LPOLESTR buffer,
    LPDWORD buflen,
    DWORD flags )
{
    static const WCHAR fmtW[] = {',','%','s','=','\"','%','s','\"',0};
    struct name *name = impl_from_IAssemblyName( iface );
    WCHAR version[30];
    unsigned int len;

    TRACE("%p, %p, %p, 0x%08x\n", iface, buffer, buflen, flags);

    if (!buflen || flags) return E_INVALIDARG;

    len = strlenW( name->name ) + 1;
    if (name->arch)    len += strlenW( archW ) + strlenW( name->arch ) + 4;
    if (name->token)   len += strlenW( tokenW ) + strlenW( name->token ) + 4;
    if (name->type)    len += strlenW( typeW ) + strlenW( name->type ) + 4;
    if (name->version) len += strlenW( versionW ) + strlenW( version ) + 4;
    if (len > *buflen)
    {
        *buflen = len;
        return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
    }
    strcpyW( buffer, name->name );
    len = strlenW( buffer );
    if (name->arch)    len += sprintfW( buffer + len, fmtW, archW, name->arch );
    if (name->token)   len += sprintfW( buffer + len, fmtW, tokenW, name->token );
    if (name->type)    len += sprintfW( buffer + len, fmtW, typeW, name->type );
    if (name->version) len += sprintfW( buffer + len, fmtW, versionW, name->version );
    return S_OK;
}

static HRESULT WINAPI name_Reserved(
    IAssemblyName *iface,
    REFIID riid,
    IUnknown *pUnkReserved1,
    IUnknown *pUnkReserved2,
    LPCOLESTR szReserved,
    LONGLONG llReserved,
    LPVOID pvReserved,
    DWORD cbReserved,
    LPVOID *ppReserved )
{
    FIXME("%p, %s, %p, %p, %s, %x%08x, %p, %d, %p\n", iface,
          debugstr_guid(riid), pUnkReserved1, pUnkReserved2,
          debugstr_w(szReserved), (DWORD)(llReserved >> 32), (DWORD)llReserved,
          pvReserved, cbReserved, ppReserved);
    return E_NOTIMPL;
}

const WCHAR *get_name_attribute( IAssemblyName *iface, enum name_attr_id id )
{
    struct name *name = impl_from_IAssemblyName( iface );

    switch (id)
    {
    case NAME_ATTR_ID_NAME:    return name->name;
    case NAME_ATTR_ID_ARCH:    return name->arch;
    case NAME_ATTR_ID_TOKEN:   return name->token;
    case NAME_ATTR_ID_TYPE:    return name->type;
    case NAME_ATTR_ID_VERSION: return name->version;
    default:
        ERR("unhandled name attribute %u\n", id);
        break;
    }
    return NULL;
}

static HRESULT WINAPI name_GetName(
    IAssemblyName *iface,
    LPDWORD buflen,
    WCHAR *buffer )
{
    const WCHAR *name;
    int len;

    TRACE("%p, %p, %p\n", iface, buflen, buffer);

    if (!buflen || !buffer) return E_INVALIDARG;

    name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
    len = strlenW( name ) + 1;
    if (len > *buflen)
    {
        *buflen = len;
        return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
    }
    strcpyW( buffer, name );
    *buflen = len + 3;
    return S_OK;
}

static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low )
{
    WORD ver[4];
    WCHAR *p, *q;
    unsigned int i;

    memset( ver, 0, sizeof(ver) );
    for (i = 0, p = version; i < 4; i++)
    {
        if (!*p) break;
        q = strchrW( p, '.' );
        if (q) *q = 0;
        ver[i] = atolW( p );
        if (!q && i < 3) break;
        p = q + 1;
    }
    *high = (ver[0] << 16) + ver[1];
    *low = (ver[2] << 16) + ver[3];
    return S_OK;
}

static HRESULT WINAPI name_GetVersion(
    IAssemblyName *iface,
    LPDWORD high,
    LPDWORD low )
{
    struct name *name = impl_from_IAssemblyName( iface );
    WCHAR *version;
    HRESULT hr;

    TRACE("%p, %p, %p\n", iface, high, low);

    if (!name->version) return HRESULT_FROM_WIN32( ERROR_NOT_FOUND );
    if (!(version = strdupW( name->version ))) return E_OUTOFMEMORY;
    hr = parse_version( version, high, low );
    HeapFree( GetProcessHeap(), 0, version );
    return hr;
}

static HRESULT WINAPI name_IsEqual(
    IAssemblyName *name1,
    IAssemblyName *name2,
    DWORD flags )
{
    FIXME("%p, %p, 0x%08x\n", name1, name2, flags);
    return E_NOTIMPL;
}

static HRESULT WINAPI name_Clone(
    IAssemblyName *iface,
    IAssemblyName **name )
{
    FIXME("%p, %p\n", iface, name);
    return E_NOTIMPL;
}

static const IAssemblyNameVtbl name_vtbl =
{
    name_QueryInterface,
    name_AddRef,
    name_Release,
    name_SetProperty,
    name_GetProperty,
    name_Finalize,
    name_GetDisplayName,
    name_Reserved,
    name_GetName,
    name_GetVersion,
    name_IsEqual,
    name_Clone
};

static WCHAR *parse_value( const WCHAR *str, unsigned int *len )
{
    WCHAR *ret;
    const WCHAR *p = str;

    if (*p++ != '\"') return NULL;
    while (*p && *p != '\"') p++;
    if (!*p) return NULL;

    *len = p - str;
    if (!(ret = HeapAlloc( GetProcessHeap(), 0, *len * sizeof(WCHAR) ))) return NULL;
    memcpy( ret, str + 1, (*len - 1) * sizeof(WCHAR) );
    ret[*len - 1] = 0;
    return ret;
}

static HRESULT parse_displayname( struct name *name, const WCHAR *displayname )
{
    const WCHAR *p, *q;
    unsigned int len;

    p = q = displayname;
    while (*q && *q != ',') q++;
    len = q - p;
    if (!(name->name = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ))) return E_OUTOFMEMORY;
    memcpy( name->name, p, len * sizeof(WCHAR) );
    name->name[len] = 0;
    if (!*q) return S_OK;

    for (;;)
    {
        p = ++q;
        while (*q && *q != '=') q++;
        if (!*q) return E_INVALIDARG;
        len = q - p;
        if (len == sizeof(archW)/sizeof(archW[0]) - 1 && !memcmp( p, archW, len * sizeof(WCHAR) ))
        {
            p = ++q;
            if (!(name->arch = parse_value( p, &len ))) return E_INVALIDARG;
            q += len;
        }
        else if (len == sizeof(tokenW)/sizeof(tokenW[0]) - 1 && !memcmp( p, tokenW, len * sizeof(WCHAR) ))
        {
            p = ++q;
            if (!(name->token = parse_value( p, &len ))) return E_INVALIDARG;
            q += len;
        }
        else if (len == sizeof(typeW)/sizeof(typeW[0]) - 1 && !memcmp( p, typeW, len * sizeof(WCHAR) ))
        {
            p = ++q;
            if (!(name->type = parse_value( p, &len ))) return E_INVALIDARG;
            q += len;
        }
        else if (len == sizeof(versionW)/sizeof(versionW[0]) - 1 && !memcmp( p, versionW, len * sizeof(WCHAR) ))
        {
            p = ++q;
            if (!(name->version = parse_value( p, &len ))) return E_INVALIDARG;
            q += len;
        }
        else return HRESULT_FROM_WIN32( ERROR_SXS_INVALID_ASSEMBLY_IDENTITY_ATTRIBUTE_NAME );
        while (*q && *q != ',') q++;
        if (!*q) break;
    }
    return S_OK;
}

/******************************************************************
 *  CreateAssemblyNameObject   (SXS.@)
 */
HRESULT WINAPI CreateAssemblyNameObject(
    LPASSEMBLYNAME *obj,
    LPCWSTR assembly,
    DWORD flags,
    LPVOID reserved )
{
    struct name *name;
    HRESULT hr;

    TRACE("%p, %s, 0x%08x, %p\n", obj, debugstr_w(assembly), flags, reserved);

    if (!obj) return E_INVALIDARG;

    *obj = NULL;
    if (!assembly || !assembly[0] || flags != CANOF_PARSE_DISPLAY_NAME)
        return E_INVALIDARG;

    if (!(name = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*name) )))
        return E_OUTOFMEMORY;

    name->IAssemblyName_iface.lpVtbl = &name_vtbl;
    name->refs = 1;

    hr = parse_displayname( name, assembly );
    if (hr != S_OK)
    {
        HeapFree( GetProcessHeap(), 0, name->name );
        HeapFree( GetProcessHeap(), 0, name->arch );
        HeapFree( GetProcessHeap(), 0, name->token );
        HeapFree( GetProcessHeap(), 0, name->type );
        HeapFree( GetProcessHeap(), 0, name->version );
        HeapFree( GetProcessHeap(), 0, name );
        return hr;
    }
    *obj = &name->IAssemblyName_iface;
    return S_OK;
}
