#ifndef _PROXY_AGENT_FINDER_IMPL_HH_
#define _PROXY_AGENT_FINDER_IMPL_HH_

// 	Copyright 07/24/01 Sun Microsystems, Inc. All Rights Reserved.

#pragma ident  " @(#)proxy_agent_finder_impl.hh	1.9E%  Sun Microsystems"

#include <rw/tvslist.h>
#include <rw/cstring.h>

#include <synch.h> 	// For read write locks

#include "em_c++utils/em_basic_types.hh"
#ifdef ORBACUS
#include <OB/CORBA.h>
#include "jidm/JIDM.h"
#else 
#ifdef ORBIX
#include "jidm/JIDMS.hh"
#else
#include "jidm/JIDM_s.hh"
#endif
#endif

#ifdef ORBACUS
typedef POA_OSIMgmtExt::ProxyAgent_tie<OSIMgmtExtProxyAgentImpl>*  OSI_ProxyAgent_tie_ptr ;
#else
typedef POA_OSIMgmtExt_ProxyAgent_tie<OSIMgmtExtProxyAgentImpl>* OSI_ProxyAgent_tie_ptr ;
#endif

class ProxyAgentFinderImpl;

class ProxyAgentControllerImpl
//    : public _sk_JIDM::_sk_ProxyAgentController
    : public POA_JIDM::ProxyAgentController,public virtual PortableServer::RefCountServantBase
{
  public:
    ProxyAgentControllerImpl(
	ProxyAgentFinderImpl* paf
    ) throw();

    virtual ~ProxyAgentControllerImpl(
    ) throw();
 
    JIDM::Criteria*
    destruction_is_allowed(
	const JIDM::Criteria& the_criteria
    ) throw (
	JIDM::InvalidCriteria,
	JIDM::CannotMeetCriteria,
 	CORBA::SystemException
    );

    void
    destroyed(
	const JIDM::Criteria& the_criteria
    ) throw (
 	CORBA::SystemException
    );

  private:
    ProxyAgentFinderImpl* proxy_agent_finder_impl_;

    // Copy and Assignment are explictly suppressed
    ProxyAgentControllerImpl(const ProxyAgentControllerImpl&);
    void operator=(const ProxyAgentControllerImpl&);
};

/******************************************************************************/
class ProxyAgentFinderImpl
//    : public _sk_JIDM::_sk_ProxyAgentFinder
    : public POA_JIDM::ProxyAgentFinder
{

  public:
    ProxyAgentFinderImpl(
	const char* finder_name = NULL
    ) throw();

    virtual ~ProxyAgentFinderImpl() throw();
 
    JIDM::ProxyAgent_ptr
    access_domain(
	const JIDM::Key& key,
	const JIDM::Criteria& criteria
    ) throw (
	JIDM::InvalidKey,
	JIDM::CannotAccess,
	JIDM::InvalidCriteria,
	JIDM::CannotMeetCriteria,
 	CORBA::SystemException
    );
    
    bool
    remove_proxy_agent_from_list(
	const JIDM::Criteria& client_access_criteria
    ) throw(
 	CORBA::SystemException
    );

    void shutdown() throw ();

  protected:
    JIDM::ProxyAgentController_var proxy_agent_controller_;
    JIDM::Key key_;
    
    RWCString host_name_;
    //RWReadersWriterLock proxy_agent_list_lock_;
	rwlock_t proxy_agent_list_lock_;
	
	RWTValSlist<OSI_ProxyAgent_tie_ptr> proxy_agent_list_ ; 

    
	// Suppressed Explicitly
    ProxyAgentFinderImpl(const ProxyAgentFinderImpl&);
    ProxyAgentFinderImpl& operator=(const ProxyAgentFinderImpl&);

    void
    authenticate_user_profile(
	const CORBA::Any& user_profile,
	RWCString& user_name
    ) throw (
	JIDM::CannotAccess,
	JIDM::InvalidCriteria,
	JIDM::CannotMeetCriteria,
	CORBA::SystemException
    );

    OSI_ProxyAgent_tie_ptr 
    find_matching_proxy_agent(
	const JIDM::Criteria& client_access_criteria
    ) throw (
	CORBA::SystemException
    );

    void
    validate_key_n_criteria(
	const JIDM::Key& the_key,
	const JIDM::Criteria& the_criteria
    ) throw (
	JIDM::InvalidKey,
	JIDM::InvalidCriteria,
	CORBA::SystemException
    );    
};


#endif //_PROXY_AGENT_FINDER_IMPL_HH_
