#if !defined(PROCESS_H)
#define PROCESS_H

#include <Image.h>

#include <string>
#include <vector>
#include <map>

class Sample;
class ProcessExec;

class Process
{
    typedef std::map< pid_t, Process* > ProcessMap;
    typedef std::map< bfd_vma, unsigned > SampleMap;
    typedef std::map< bfd_vma, std::string > LoadableImageMap;

    static ProcessMap processMap;

    pid_t m_pid;
    unsigned m_sampleCount;
    std::string m_name;

    SampleMap m_kernelSamples;
    SampleMap m_processSamples;

    LoadableImageMap m_loadableImageMap;
    FunctionLocationMap m_functionLocationMap;

    Process( const Sample& sample );
    Process( const ProcessExec& processExec );

    class ProcessSampleCompare
    {
    public:
        bool operator()( const Process* lhs, const Process* rhs )
        {
            return lhs -> m_sampleCount > rhs -> m_sampleCount;
        }
    };

public:
    typedef std::vector< Process* > ActiveProcessList;

    static void fillProcessMap();

    static Process& getProcess( const Sample& sample );
    static Process& getProcess( const ProcessExec& processExec );

    static Process* getProcess( pid_t pid )
    {
        return processMap[ pid ];
    }

    static void collectAllLocations( LocationList& locationList );
    static void mapAllFunctions( LocationList& locationList );
    static void collectActiveProcesses( ActiveProcessList& activeProcessList );

    std::string getLoadableImageName( const Location& location, uintptr_t& loadOffset );

    pid_t getPid() const
    {
        return m_pid;
    }

    const std::string& getName() const
    {
        return m_name;
    }

    unsigned getSampleCount() const
    {
        return m_sampleCount;
    }

    void addSample( const Sample& sample );
    void collectLocations( LocationList& locationList );
    void getFunctionList( FunctionList& functionList );
};

#endif // #if !defined(PROCESS_H)
