#pragma once

#define BOOST_THREAD_USE_LIB
#include "context/CallerController.h"
#include "util/simpleobject/AgString.h"
#include "util/simpleobject/AgDate.h"
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread/mutex.hpp>
#include <set>
#include <map>
#include <list>

class AbstractCallerController : public CallerController, public boost::enable_shared_from_this<AbstractCallerController>
{
private:
    static std::set<CallerController*>  CONTROLLERS;
    AgString username;
	CallerDataPtr callerData;
    bool loggedIn;
    AgString type;
    AgString address;
    AgDate creationTime;
	std::map<AgString, AgString> properties;
    static boost::mutex mutex;

public:
    bool isLoggedIn();
    bool isPermissionCheckingEnabled();
	PermissionCachePtr getPermissionCache();
	CallerDataPtr getCallerData();
    std::map<AgString, AgString> getProperties();


    void setLoggedIn(bool loggedIn);

    void sendFeedback(int level, const AgString & message);
    static std::list< CallerController* >  getControllers();
    AgString toString();
    PermissionsPtr getPermissions();
    AgString getUsername();

    void setUsername(const AgString & username);

    AgString  getInheritedUsername();
    AgString  getEffectiveUsername();
    AgString  getType();
    void setType(const AgString & type);
    AgString getAddress();
    void setAddress(const AgString & address);
    void login(const AgString & username, const AgString & inheritedUsername, PermissionsPtr permissons) ;
    AgDate getCreationTime();
    void logout();

	AbstractCallerController(CallerDataPtr callerData);

};
