/*
 * 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)
        {
            WINE_WARN("TowerExplode failed %lu\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, %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;
}
