/*
 * 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, %u, %p, %u, %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)
        {
            WINE_WARN("TowerExplode failed %u\n", rpc_status);
            *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, %u, %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, %u, %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, %d, %p, %p, %p): stub\n", h, object_speced, object, tower, status);

    *status = EPT_S_CANT_PERFORM_OP;
}
