/*
 * IAssemblyEnum implementation
 *
 * Copyright 2008 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
#define NONAMELESSUNION
#define NONAMELESSSTRUCT

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"
#include "guiddef.h"
#include "fusion.h"
#include "corerror.h"
#include "fusionpriv.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(fusion);

typedef struct _tagASMNAME
{
    struct list entry;
    IAssemblyName *name;
} ASMNAME;

typedef struct
{
    IAssemblyEnum IAssemblyEnum_iface;

    struct list assemblies;
    struct list *iter;
    LONG ref;
} IAssemblyEnumImpl;

static inline IAssemblyEnumImpl *impl_from_IAssemblyEnum(IAssemblyEnum *iface)
{
    return CONTAINING_RECORD(iface, IAssemblyEnumImpl, IAssemblyEnum_iface);
}

static HRESULT WINAPI IAssemblyEnumImpl_QueryInterface(IAssemblyEnum *iface,
                                                       REFIID riid, LPVOID *ppobj)
{
    IAssemblyEnumImpl *This = impl_from_IAssemblyEnum(iface);

    TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);

    *ppobj = NULL;

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IAssemblyEnum))
    {
        IAssemblyEnum_AddRef(iface);
        *ppobj = This;
        return S_OK;
    }

    WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj);
    return E_NOINTERFACE;
}

static ULONG WINAPI IAssemblyEnumImpl_AddRef(IAssemblyEnum *iface)
{
    IAssemblyEnumImpl *This = impl_from_IAssemblyEnum(iface);
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before = %u)\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IAssemblyEnumImpl_Release(IAssemblyEnum *iface)
{
    IAssemblyEnumImpl *This = impl_from_IAssemblyEnum(iface);
    ULONG refCount = InterlockedDecrement(&This->ref);
    struct list *item, *cursor;

    TRACE("(%p)->(ref before = %u)\n", This, refCount + 1);

    if (!refCount)
    {
        LIST_FOR_EACH_SAFE(item, cursor, &This->assemblies)
        {
            ASMNAME *asmname = LIST_ENTRY(item, ASMNAME, entry);

            list_remove(&asmname->entry);
            IAssemblyName_Release(asmname->name);
            HeapFree(GetProcessHeap(), 0, asmname);
        }

        HeapFree(GetProcessHeap(), 0, This);
    }

    return refCount;
}

static HRESULT WINAPI IAssemblyEnumImpl_GetNextAssembly(IAssemblyEnum *iface,
                                                        LPVOID pvReserved,
                                                        IAssemblyName **ppName,
                                                        DWORD dwFlags)
{
    IAssemblyEnumImpl *asmenum = impl_from_IAssemblyEnum(iface);
    ASMNAME *asmname;

    TRACE("(%p, %p, %p, %d)\n", iface, pvReserved, ppName, dwFlags);

    if (!ppName)
        return E_INVALIDARG;

    asmname = LIST_ENTRY(asmenum->iter, ASMNAME, entry);
    if (!asmname)
        return S_FALSE;

    *ppName = asmname->name;
    IAssemblyName_AddRef(*ppName);

    asmenum->iter = list_next(&asmenum->assemblies, asmenum->iter);

    return S_OK;
}

static HRESULT WINAPI IAssemblyEnumImpl_Reset(IAssemblyEnum *iface)
{
    IAssemblyEnumImpl *asmenum = impl_from_IAssemblyEnum(iface);

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

    asmenum->iter = list_head(&asmenum->assemblies);
    return S_OK;
}

static HRESULT WINAPI IAssemblyEnumImpl_Clone(IAssemblyEnum *iface,
                                               IAssemblyEnum **ppEnum)
{
    FIXME("(%p, %p) stub!\n", iface, ppEnum);
    return E_NOTIMPL;
}

static const IAssemblyEnumVtbl AssemblyEnumVtbl = {
    IAssemblyEnumImpl_QueryInterface,
    IAssemblyEnumImpl_AddRef,
    IAssemblyEnumImpl_Release,
    IAssemblyEnumImpl_GetNextAssembly,
    IAssemblyEnumImpl_Reset,
    IAssemblyEnumImpl_Clone
};

static void build_file_mask(IAssemblyName *name, int depth, const WCHAR *path,
                            const WCHAR *prefix, WCHAR *buf)
{
    static const WCHAR star[] = {'*',0};
    static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0};
    static const WCHAR sss_fmt[] = {'%','s','\\','%','s','_','_','%','s',0};
    static const WCHAR ssss_fmt[] = {'%','s','\\','%','s','%','s','_','_','%','s',0};
    static const WCHAR ver_fmt[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
    static const WCHAR star_fmt[] = {'%','s','\\','*',0};
    static const WCHAR star_prefix_fmt[] = {'%','s','\\','%','s','*',0};
    WCHAR disp[MAX_PATH], version[24]; /* strlen("65535") * 4 + 3 + 1 */
    LPCWSTR verptr, pubkeyptr;
    HRESULT hr;
    DWORD size, major_size, minor_size, build_size, revision_size;
    WORD major, minor, build, revision;
    WCHAR token_str[TOKEN_LENGTH + 1];
    BYTE token[BYTES_PER_TOKEN];

    if (!name)
    {
        if (prefix && depth == 1)
            sprintfW(buf, star_prefix_fmt, path, prefix);
        else
            sprintfW(buf, star_fmt, path);
        return;
    }
    if (depth == 0)
    {
        size = MAX_PATH;
        *disp = '\0';
        hr = IAssemblyName_GetName(name, &size, disp);
        if (SUCCEEDED(hr))
            sprintfW(buf, ss_fmt, path, disp);
        else
            sprintfW(buf, ss_fmt, path, star);
    }
    else if (depth == 1)
    {
        major_size = sizeof(major);
        IAssemblyName_GetProperty(name, ASM_NAME_MAJOR_VERSION, &major, &major_size);

        minor_size = sizeof(minor);
        IAssemblyName_GetProperty(name, ASM_NAME_MINOR_VERSION, &minor, &minor_size);

        build_size = sizeof(build);
        IAssemblyName_GetProperty(name, ASM_NAME_BUILD_NUMBER, &build, &build_size);

        revision_size = sizeof(revision);
        IAssemblyName_GetProperty(name, ASM_NAME_REVISION_NUMBER, &revision, &revision_size);

        if (!major_size || !minor_size || !build_size || !revision_size) verptr = star;
        else
        {
            sprintfW(version, ver_fmt, major, minor, build, revision);
            verptr = version;
        }

        size = sizeof(token);
        IAssemblyName_GetProperty(name, ASM_NAME_PUBLIC_KEY_TOKEN, token, &size);

        if (!size) pubkeyptr = star;
        else
        {
            token_to_str(token, token_str);
            pubkeyptr = token_str;
        }

        if (prefix)
            sprintfW(buf, ssss_fmt, path, prefix, verptr, pubkeyptr);
        else
            sprintfW(buf, sss_fmt, path, verptr, pubkeyptr);
    }
}

static int compare_assembly_names(ASMNAME *asmname1, ASMNAME *asmname2)
{
    int ret;
    WORD version1, version2;
    WCHAR name1[MAX_PATH], name2[MAX_PATH];
    WCHAR token_str1[TOKEN_LENGTH + 1], token_str2[TOKEN_LENGTH + 1];
    BYTE token1[BYTES_PER_TOKEN], token2[BYTES_PER_TOKEN];
    DWORD size, i;

    size = sizeof(name1);
    IAssemblyName_GetProperty(asmname1->name, ASM_NAME_NAME, name1, &size);
    size = sizeof(name2);
    IAssemblyName_GetProperty(asmname2->name, ASM_NAME_NAME, name2, &size);

    if ((ret = strcmpiW(name1, name2))) return ret;

    for (i = ASM_NAME_MAJOR_VERSION; i < ASM_NAME_CULTURE; i++)
    {
        size = sizeof(version1);
        IAssemblyName_GetProperty(asmname1->name, i, &version1, &size);
        size = sizeof(version2);
        IAssemblyName_GetProperty(asmname2->name, i, &version2, &size);

        if (version1 < version2) return -1;
        if (version1 > version2) return 1;
    }

    /* FIXME: compare cultures */

    size = sizeof(token1);
    IAssemblyName_GetProperty(asmname1->name, ASM_NAME_PUBLIC_KEY_TOKEN, token1, &size);
    size = sizeof(token2);
    IAssemblyName_GetProperty(asmname2->name, ASM_NAME_PUBLIC_KEY_TOKEN, token2, &size);

    token_to_str(token1, token_str1);
    token_to_str(token2, token_str2);

    if ((ret = strcmpiW(token_str1, token_str2))) return ret;

    return 0;
}

/* insert assembly in list preserving sort order */
static void insert_assembly(struct list *assemblies, ASMNAME *to_insert)
{
    struct list *item;

    LIST_FOR_EACH(item, assemblies)
    {
        ASMNAME *name = LIST_ENTRY(item, ASMNAME, entry);

        if (compare_assembly_names(name, to_insert) > 0)
        {
            list_add_before(&name->entry, &to_insert->entry);
            return;
        }
    }
    list_add_tail(assemblies, &to_insert->entry);
}

static HRESULT enum_gac_assemblies(struct list *assemblies, IAssemblyName *name,
                                   int depth, const WCHAR *prefix, LPWSTR path)
{
    static const WCHAR dot[] = {'.',0};
    static const WCHAR dotdot[] = {'.','.',0};
    static const WCHAR dblunder[] = {'_','_',0};
    static const WCHAR path_fmt[] = {'%','s','\\','%','s','\\','%','s','.','d','l','l',0};
    static const WCHAR name_fmt[] = {'%','s',',',' ','V','e','r','s','i','o','n','=','%','s',',',' ',
        'C','u','l','t','u','r','e','=','n','e','u','t','r','a','l',',',' ',
        'P','u','b','l','i','c','K','e','y','T','o','k','e','n','=','%','s',0};
    static const WCHAR ss_fmt[] = {'%','s','\\','%','s',0};
    WIN32_FIND_DATAW ffd;
    WCHAR buf[MAX_PATH], disp[MAX_PATH], asmpath[MAX_PATH], *ptr;
    static WCHAR parent[MAX_PATH];
    ASMNAME *asmname;
    HANDLE hfind;
    HRESULT hr = S_OK;

    build_file_mask(name, depth, path, prefix, buf);
    hfind = FindFirstFileW(buf, &ffd);
    if (hfind == INVALID_HANDLE_VALUE)
        return S_OK;

    do
    {
        if (!lstrcmpW(ffd.cFileName, dot) || !lstrcmpW(ffd.cFileName, dotdot))
            continue;

        if (depth == 0)
        {
            if (name)
                ptr = strrchrW(buf, '\\') + 1;
            else
                ptr = ffd.cFileName;

            lstrcpyW(parent, ptr);
        }
        else if (depth == 1)
        {
            const WCHAR *token, *version = ffd.cFileName;

            sprintfW(asmpath, path_fmt, path, ffd.cFileName, parent);
            ptr = strstrW(ffd.cFileName, dblunder);
            *ptr = '\0';
            token = ptr + 2;

            if (prefix)
            {
                unsigned int prefix_len = strlenW(prefix);
                if (strlenW(ffd.cFileName) >= prefix_len &&
                    !memicmpW(ffd.cFileName, prefix, prefix_len))
                    version += prefix_len;
            }
            sprintfW(disp, name_fmt, parent, version, token);

            asmname = HeapAlloc(GetProcessHeap(), 0, sizeof(ASMNAME));
            if (!asmname)
            {
                hr = E_OUTOFMEMORY;
                break;
            }

            hr = CreateAssemblyNameObject(&asmname->name, disp,
                                          CANOF_PARSE_DISPLAY_NAME, NULL);
            if (FAILED(hr))
            {
                HeapFree(GetProcessHeap(), 0, asmname);
                break;
            }

            hr = IAssemblyName_SetPath(asmname->name, asmpath);
            if (FAILED(hr))
            {
                IAssemblyName_Release(asmname->name);
                HeapFree(GetProcessHeap(), 0, asmname);
                break;
            }

            insert_assembly(assemblies, asmname);
            continue;
        }

        sprintfW(buf, ss_fmt, path, ffd.cFileName);
        hr = enum_gac_assemblies(assemblies, name, depth + 1, prefix, buf);
        if (FAILED(hr))
            break;
    } while (FindNextFileW(hfind, &ffd) != 0);

    FindClose(hfind);
    return hr;
}

static HRESULT enumerate_gac(IAssemblyEnumImpl *asmenum, IAssemblyName *pName)
{
    static const WCHAR gac[] = {'\\','G','A','C',0};
    static const WCHAR gac_32[] = {'\\','G','A','C','_','3','2',0};
    static const WCHAR gac_64[] = {'\\','G','A','C','_','6','4',0};
    static const WCHAR gac_msil[] = {'\\','G','A','C','_','M','S','I','L',0};
    static const WCHAR v40[] = {'v','4','.','0','_',0};
    WCHAR path[MAX_PATH], buf[MAX_PATH];
    SYSTEM_INFO info;
    HRESULT hr;
    DWORD size;

    size = MAX_PATH;
    hr = GetCachePath(ASM_CACHE_ROOT_EX, buf, &size);
    if (FAILED(hr))
        return hr;

    strcpyW(path, buf);
    GetNativeSystemInfo(&info);
    if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
    {
        strcpyW(path + size - 1, gac_64);
        hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, v40, path);
        if (FAILED(hr))
            return hr;
    }
    strcpyW(path + size - 1, gac_32);
    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, v40, path);
    if (FAILED(hr))
        return hr;

    strcpyW(path + size - 1, gac_msil);
    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, v40, path);
    if (FAILED(hr))
        return hr;

    size = MAX_PATH;
    hr = GetCachePath(ASM_CACHE_ROOT, buf, &size);
    if (FAILED(hr))
        return hr;

    strcpyW(path, buf);
    if (info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
    {
        strcpyW(path + size - 1, gac_64);
        hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path);
        if (FAILED(hr))
            return hr;
    }
    strcpyW(path + size - 1, gac_32);
    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path);
    if (FAILED(hr))
        return hr;

    strcpyW(path + size - 1, gac_msil);
    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path);
    if (FAILED(hr))
        return hr;

    strcpyW(path + size - 1, gac);
    hr = enum_gac_assemblies(&asmenum->assemblies, pName, 0, NULL, path);
    if (FAILED(hr))
        return hr;

    return S_OK;
}

/******************************************************************
 *  CreateAssemblyEnum   (FUSION.@)
 */
HRESULT WINAPI CreateAssemblyEnum(IAssemblyEnum **pEnum, IUnknown *pUnkReserved,
                                  IAssemblyName *pName, DWORD dwFlags, LPVOID pvReserved)
{
    IAssemblyEnumImpl *asmenum;
    HRESULT hr;

    TRACE("(%p, %p, %p, %08x, %p)\n", pEnum, pUnkReserved,
          pName, dwFlags, pvReserved);

    if (!pEnum)
        return E_INVALIDARG;

    if (dwFlags == 0 || dwFlags == ASM_CACHE_ROOT)
        return E_INVALIDARG;

    asmenum = HeapAlloc(GetProcessHeap(), 0, sizeof(IAssemblyEnumImpl));
    if (!asmenum)
        return E_OUTOFMEMORY;

    asmenum->IAssemblyEnum_iface.lpVtbl = &AssemblyEnumVtbl;
    asmenum->ref = 1;
    list_init(&asmenum->assemblies);

    if (dwFlags & ASM_CACHE_GAC)
    {
        hr = enumerate_gac(asmenum, pName);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, asmenum);
            return hr;
        }
    }

    asmenum->iter = list_head(&asmenum->assemblies);
    *pEnum = &asmenum->IAssemblyEnum_iface;

    return S_OK;
}
