#ifndef IMSVR_HH_
#define IMSVR_HH_
#include <vector>
#include <bitset>
#include "basictype.hh"
#include "IMAccept.hh"
#include "IMAuth.hh"
#include "IMUserMgr.hh"
#include "IMUtil.hh"
#include "IMKeyUtils.hh"
#include "lexmlconf.h"

class IMSvrCfg;
class IMConnection;
class LEMgr;
class IMProtocol;

class IMSvr : public IMAccept
{
    IMSvrCfg *pcfg;
    IMUserMgr usermgr;
    LEMgr *plemgr;
    IMProtocol *pimprotocol;

    IMConnection* create_imconnection(
	IMUser *puser,
	const string &hostname
    );

    enum {
        CAUGHT_SIGTERM,
        CAUGHT_SIGHUP,
        CAUGHT_LAST
    };

    std::bitset<CAUGHT_LAST> signal_flag;

  protected:
    // configuration methods.
    bool config_lepath(
	const char* lepath
    );
    bool config_listenaddress(
	IMSocketAddressVec& addrvec
    );
    bool config_le (
       const char* lepath,
       IIIMLEXMLConf &xml,
       bool preferred_loading
    );
    bool set_nsmap_config (
       IMNsMapStruct *nsmp,
       int num_entries
    );

  public:
    // IMAccept realization.

    virtual bool request_accept(
	int fd
    );
    virtual IMHandler* request_connect(
	int fd,
	const u16string &username,
	const string &hostname,
	const u16string &password,
	const IMAuthList &authlist
    );
    
  public:
    LEMgr* get_lemgr()
    { return plemgr; }

    IMKeySpecList get_conversionkeys() const;

    enum IMSVR_EXIT_CODE {
	    IMSVR_EXIT_SUCCESS = 0,
	    IMSVR_CONFIG_ERROR = 100,
	    IMSVR_SYSTEM_ERROR = 255
    };

    void reload();
    void terminate();
    int start();
    IMSvr(IMSvrCfg *p_cfg);
    virtual ~IMSvr();

  friend class IMSvrCfg;
};

#endif /* not IMSVR_HH_ */

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
