/**
 * @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_RPCSEARCHPROVIDER_H
#define __IWREMOTE_RPCSEARCHPROVIDER_H

#include <iwremote/searchprovider.h>
#include "rpcsearchserver.h"

namespace iwear
{
    namespace net
    {

class CallHandler;
class RPCSearch;
class CallManager;

struct RPCSearchHandle: public SearchHandle
{
    RPCSearchHandle( search_call sc ): SearchHandle(sc) { }
    list<pair<CallHandler*, RPCSearch*> > searches;
};

/**
 * We hold a list of rpcsearch objects which we have to keep in sync with the
 * hosts known to the system. We ask a certain number of hosts in the system.
 */
class RPCSearchProvider : public SearchProvider, public RPCSearch_Server
{
private:
protected:

    const uid id;

    uint16_t recdepth;

    uint16_t branchf;

    typedef
    multimap<hostid_t,RPCSearch*> SearcherList;
    SearcherList searchers;

    void update_searcherslist( void );

    /**
     * XXX add the timeout
     * These are the search IDs that were already done.
     */
    set<uint32_t> searched;

    /**
     * The following functions are the outside rpc interface of this class, not
     * to be used locally.
     */
    virtual pair<list<HostInformation >,list<ObjectInformation > >  
	search( const uid& arg0, const uint32_t& hops, const uint32_t& sid );
    virtual pair<list<HostInformation >,list<ObjectInformation > >  
	search( const uid& arg0, const uint32_t& cid, const uint32_t& hops, const uint32_t& sid );

    virtual pair<list<HostInformation >,list<ObjectInformation > >  
	search( const uint32_t& arg1, const uint32_t& hops, const uint32_t& sid );
    virtual pair<list<HostInformation >,list<ObjectInformation > >  
	search( const string& arg2, const uint32_t& hops, const uint32_t& sid );

    virtual list<HostInformation >  search_reachable( const uid& arg4, const uint32_t& hops, 
	    const uint32_t& sid );

    virtual list<HostInformation >  search_reachable( CallHandler* ch, const uid& arg4,
	    const uint32_t& hops, const uint32_t& sid );

    virtual void tell( const list<HostInformation >& arg3, 
	    const list<ObjectInformation >& arg4 );
    virtual const uid& get_uid( void ) const;
    virtual const string& get_name( void ) const;

    HostConnector fixup_hostinfo( const HostInformation& hi, RemoteObject* ro );
    virtual void about_to_call( uint32_t funcid, uint32_t fver, const hostid_t& caller );
    virtual bool may_associate( const hostid_t& caller );

    void remember_actual_caller( void );

public:

    RPCSearchProvider( CallManager* c );
    virtual ~RPCSearchProvider();

    virtual void set_recursion_depth( uint32_t rd ) { recdepth = rd; }
    virtual void set_branch_factor( uint32_t rd ) { branchf = rd; }
    void load_configuration( Configuration& conf );

    /**
     * This is the public interface for local use by the managers.
     */
    virtual SearchHandle* start_search( const uid&, uint32_t hops, uint32_t sid = 0 );

    virtual SearchHandle* start_search( uint32_t cid, uint32_t hops, uint32_t sid = 0 );

    virtual SearchHandle* start_search( const string& exp, uint32_t hops, uint32_t sid = 0 );

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

    virtual SearchResult finish_search( SearchHandle* );
};

}
}
#endif
