#ifndef PapiConnection_hpp
#define PapiConnection_hpp

#include <string>
#include <vector>

#include <papi/papi.h>
#include "XmlUpdateLayer.hpp"
#include "Exceptions.hpp"

namespace apoc { namespace legacy {

class PapiLayer : public XmlUpdateLayer
{
    public :
        PapiLayer(const char *aData, int aSize, const std::string& aTimestamp) ;
        virtual ~PapiLayer(void) {}

    protected :
    private :
        std::string mTimestamp ;
} ;
    
class PapiException : public Exception
{
    public :
        PapiException(const std::string& aMessage, PAPIStatus aStatus)
        : Exception(aMessage), mStatus(aStatus) {}

        const PAPIStatus& getStatus(void) const { return mStatus ; }
    protected :
    private :
        PAPIStatus mStatus ;
} ;

class PapiConnection
{
    public :
        PapiConnection(const std::string& aEntity, 
                       PAPIConnectionListener aListener = NULL,
                       void *aContext = NULL) ;
        ~PapiConnection(void) ;

        int acquire(void) { return ++ mRefCount ; }
        int release(void) { return -- mRefCount ; }

        const std::string& getEntity(void) const { return mEntity ; }

        void readComponentLayers(const std::string& aComponent,
                                 std::vector<PapiLayer>& aLayers) const ;
        void listComponentNames(const std::string& aFilter, 
                                std::vector<std::string>& aComponents) const ;
        PAPIListenerId addListener(const std::string& aComponent, 
                                   PAPIListener aListener,
                                   void *aUserData) ;
        void removeListener(PAPIListenerId aListener) ; 
    protected :
    private :
        PAPI *mConnection ;
        int mRefCount ;
        std::string mEntity ;
} ;

} } // apoc.legacy

#endif // PapiConnection_hpp

