/*
 * Endpoint Mapper
 *
 * Copyright (C) 2007 Robert Shearman 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 "epm.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(ole);

struct registered_ept_entry
{
    struct list entry;
    GUID object;
    RPC_SYNTAX_IDENTIFIER iface;
    RPC_SYNTAX_IDENTIFIER syntax;
    char *protseq;
    char *endpoint;
    char *address;
    char annotation[ept_max_annotation_size];
};

static struct list registered_ept_entry_list = LIST_INIT(registered_ept_entry_list);

static CRITICAL_SECTION csEpm;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &csEpm,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
    0, 0, { (DWORD_PTR)(__FILE__ ": csEpm") }
};
static CRITICAL_SECTION csEpm = { &critsect_debug, -1, 0, 0, 0, 0 };

static const UUID nil_object;

/* must be called inside csEpm */
static void delete_registered_ept_entry(struct registered_ept_entry *entry)
{
    I_RpcFree(entry->protseq);
    I_RpcFree(entry->endpoint);
    I_RpcFree(entry->address);
    list_remove(&entry->entry);
    HeapFree(GetProcessHeap(), 0, entry);
}

static struct registered_ept_entry *find_ept_entry(
    const RPC_SYNTAX_IDENTIFIER *iface, const RPC_SYNTAX_IDENTIFIER *syntax,
    const char *protseq, const char *endpoint, const char *address,
    const UUID *object)
{
    struct registered_ept_entry *entry;
    LIST_FOR_EACH_ENTRY(entry, &registered_ept_entry_list, struct registered_ept_entry, entry)
    {
        if (memcmp(&entry->iface, iface, sizeof(RPC_SYNTAX_IDENTIFIER))) continue;
        if (memcmp(&entry->syntax, syntax, sizeof(RPC_SYNTAX_IDENTIFIER))) continue;
        if (strcmp(entry->protseq, protseq)) continue;
        if (memcmp(&entry->object, object, sizeof(UUID))) continue;
	WINE_TRACE("found entry with iface %d.%d %s, syntax %d.%d %s, protseq %s, object %s\n",
                   entry->iface.SyntaxVersion.MajorVersion, entry->iface.SyntaxVersion.MinorVersion,
                   wine_dbgstr_guid(&entry->iface.SyntaxGUID),
                   entry->syntax.SyntaxVersion.MajorVersion, entry->syntax.SyntaxVersion.MinorVersion,
                   wine_dbgstr_guid(&entry->syntax.SyntaxGUID), protseq,
                   wine_dbgstr_guid(&entry->object));
        return entry;
    }
    WINE_TRACE("not found\n");
    return NULL;
}

void __RPC_USER ept_lookup_handle_t_rundown(ept_lookup_handle_t entry_handle)
{
    WINE_FIXME("%p\n", entry_handle);
}

void ept_insert(handle_t h,
                unsigned32 num_ents,
                ept_entry_t entries[],
                boolean32 replace,
                error_status_t *status)
{
    unsigned32 i;
    RPC_STATUS rpc_status;

    WINE_TRACE("(%p, %lu, %p, %lu, %p)\n", h, num_ents, entries, replace, status);

    *status = RPC_S_OK;

    EnterCriticalSection(&csEpm);

    for (i = 0; i < num_ents; i++)
    {
        struct registered_ept_entry *entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
        if (!entry)
        {
            /* FIXME: cleanup code to delete added entries */
            *status = EPT_S_CANT_PERFORM_OP;
            break;
        }
        list_init(&entry->entry);
        memcpy(entry->annotation, entries[i].annotation, sizeof(entries[i].annotation));
        rpc_status = TowerExplode(entries[i].tower, &entry->iface, &entry->syntax,
                                  &entry->protseq, &entry->endpoint,
                                  &entry->address);
        if (rpc_status != RPC_S_OK)
        {
            *status = rpc_status;
            break; /* FIXME: more cleanup? */
        }

        entry->object = entries[i].object;

        if (replace)
        {
            /* FIXME: correct find algorithm */
            struct registered_ept_entry *old_entry = find_ept_entry(&entry->iface, &entry->syntax, entry->protseq, entry->endpoint, entry->address, &entry->object);
            if (old_entry) delete_registered_ept_entry(old_entry);
        }
        list_add_tail(&registered_ept_entry_list, &entry->entry);
    }

    LeaveCriticalSection(&csEpm);
}

void ept_delete(handle_t h,
                unsigned32 num_ents,
                ept_entry_t entries[],
                error_status_t *status)
{
    unsigned32 i;
    RPC_STATUS rpc_status;

    *status = RPC_S_OK;

    WINE_TRACE("(%p, %lu, %p, %p)\n", h, num_ents, entries, status);

    EnterCriticalSection(&csEpm);

    for (i = 0; i < num_ents; i++)
    {
        struct registered_ept_entry *entry;
        RPC_SYNTAX_IDENTIFIER iface, syntax;
        char *protseq;
        char *endpoint;
        char *address;
        rpc_status = TowerExplode(entries[i].tower, &iface, &syntax, &protseq,
                                  &endpoint, &address);
        if (rpc_status != RPC_S_OK)
            break;
        entry = find_ept_entry(&iface, &syntax, protseq, endpoint, address, &entries[i].object);
        if (entry)
            delete_registered_ept_entry(entry);
        else
        {
            *status = EPT_S_NOT_REGISTERED;
            break;
        }
        I_RpcFree(protseq);
        I_RpcFree(endpoint);
        I_RpcFree(address);
    }

    LeaveCriticalSection(&csEpm);
}

void ept_lookup(handle_t h,
                unsigned32 inquiry_type,
                uuid_p_t object,
                rpc_if_id_p_t interface_id,
                unsigned32 vers_option,
                ept_lookup_handle_t *entry_handle,
                unsigned32 max_ents,
                unsigned32 *num_ents,
                ept_entry_t entries[],
                error_status_t *status)
{
    WINE_FIXME("(%p, %p, %p): stub\n", h, entry_handle, status);

    *status = EPT_S_CANT_PERFORM_OP;
}

void ept_map(handle_t h,
             uuid_p_t object,
             twr_p_t map_tower,
             ept_lookup_handle_t *entry_handle,
             unsigned32 max_towers,
             unsigned32 *num_towers,
             twr_p_t *towers,
             error_status_t *status)
{
    RPC_STATUS rpc_status;
    RPC_SYNTAX_IDENTIFIER iface, syntax;
    char *protseq;
    struct registered_ept_entry *entry;

    *status = RPC_S_OK;
    *num_towers = 0;

    WINE_TRACE("(%p, %p, %p, %p, %lu, %p, %p, %p)\n", h, object, map_tower,
          entry_handle, max_towers, num_towers, towers, status);

    rpc_status = TowerExplode(map_tower, &iface, &syntax, &protseq,
                              NULL, NULL);
    if (rpc_status != RPC_S_OK)
    {
        *status = rpc_status;
        return;
    }

    EnterCriticalSection(&csEpm);

    LIST_FOR_EACH_ENTRY(entry, &registered_ept_entry_list, struct registered_ept_entry, entry)
    {
        if (IsEqualGUID(&entry->iface.SyntaxGUID, &iface.SyntaxGUID) &&
            (entry->iface.SyntaxVersion.MajorVersion == iface.SyntaxVersion.MajorVersion) &&
            (entry->iface.SyntaxVersion.MinorVersion >= iface.SyntaxVersion.MinorVersion) &&
            !memcmp(&entry->syntax, &syntax, sizeof(syntax)) &&
            !strcmp(entry->protseq, protseq) &&
            ((!object && IsEqualGUID(&entry->object, &nil_object)) || IsEqualGUID(object, &entry->object)))
        {
            if (*num_towers < max_towers)
            {
                rpc_status = TowerConstruct(&entry->iface, &entry->syntax,
                                            entry->protseq, entry->endpoint,
                                            entry->address,
                                            &towers[*num_towers]);
                if (rpc_status != RPC_S_OK)
                {
                    *status = rpc_status;
                    break; /* FIXME: more cleanup? */
                }
            }
            (*num_towers)++;
        }
    }

    LeaveCriticalSection(&csEpm);
}

void ept_lookup_handle_free(handle_t h,
                            ept_lookup_handle_t *entry_handle,
                            error_status_t *status)
{
    WINE_FIXME("(%p, %p, %p): stub\n", h, entry_handle, status);

    *status = EPT_S_CANT_PERFORM_OP;
}

void ept_inq_object(handle_t h,
                    GUID *ept_object,
                    error_status_t *status)
{
    WINE_FIXME("(%p, %p, %p): stub\n", h, ept_object, status);

    *status = EPT_S_CANT_PERFORM_OP;
}

void ept_mgmt_delete(handle_t h,
                     boolean32 object_speced,
                     uuid_p_t object,
                     twr_p_t tower,
                     error_status_t *status)
{
    WINE_FIXME("(%p, %ld, %p, %p, %p): stub\n", h, object_speced, object, tower, status);

    *status = EPT_S_CANT_PERFORM_OP;
}
