/**
 * @file
 * $Id: socketprovider.h 2579 2005-10-04 16:15:50Z plasmahh $
 * $Revision: 2579 $
 * $Author: plasmahh $
 * $Date: 2005-10-04 18:15:50 +0200 (Di, 04 Okt 2005) $
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework 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 General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWREMOTE_SEARCHPROVIDER_H
#define __IWREMOTE_SEARCHPROVIDER_H

#include <list>
#include <map>

#include <iwear/threadlocked.h>
#include <iwremote/protocol.h>

using std::pair;
using std::list;

namespace iwear
{
    namespace net
    {

class HostConnector;
class RemoteDescriptor;
class CallManager;

enum search_call {
    search_oid,
    search_cid,
    search_oid_cid,
    search_name,
    num_search_call
};

struct SearchHandle
{
    search_call searched;
    
    SearchHandle( search_call sc ) : searched(sc) { }
    /**
     * Dont allow to actuall allocate one of those
     */
    virtual ~SearchHandle() = 0;
};

inline SearchHandle::~SearchHandle( )
{
}

typedef pair<
	list<HostConnector> ,
	list<RemoteDescriptor> > SearchResult;
/**
 * The searchprovider provides facilities to search for different objects in an
 * abstract, protocol independent way. One of the planned providers is a
 * remoteobject based one that simply asks other remote hosts via a remote
 * interface whether they have some objects. As this might result in poor
 * search performance on sparse networks, there is also the idea to use
 * something like the edonkey network for searching.
 */
class SearchProvider: public virtual ThreadLocked
{
private:
protected:
    CallManager* cman;
public:
    SearchProvider( CallManager* c) : cman(c) { }
    virtual ~SearchProvider() { }

    /**
     * Override this function for searchproviders that can make sense of it.
     * (e.g. pure dictionary based ones would not have a use for this)
     */
    virtual void set_recursion_depth( uint32_t ) { }
    
    /**
     * Search for a specific object uid. Ideally we get only one
     * answer back with this so a list seems to be too big. On the
     * other hand the host might know either multiple ways to reach
     * the uid, or several people claim to have the same one.
     */
    virtual SearchHandle* start_search( const oid_t&, uint32_t hops, uint32_t sid = 0 ) = 0;

    virtual SearchHandle* start_search( const oid_t&, cid_t cid, uint32_t hops, uint32_t sid ) = 0;

    /**
     * Search for a specific class implementations
     */
    virtual SearchHandle* start_search( cid_t cid, uint32_t hops, uint32_t sid = 0 ) = 0;

    /**
     * Searches for an object that matches the string. In the first
     * beta versions this will only mean that the string should be
     * part of the name. In later versions we want to have a
     * regular expession search.
     */
    virtual SearchHandle* start_search( const std::string& exp, uint32_t hops, uint32_t sid = 0 ) = 0;

    virtual SearchResult finish_search( SearchHandle* ) = 0;
};

}
}
#endif
