/**
 * @file profile_container.h
 * Container associating symbols and samples
 *
 * @remark Copyright 2002, 2003 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#ifndef PROFILE_CONTAINER_H
#define PROFILE_CONTAINER_H

#include <string>
#include <vector>

#include "profile.h"
#include "utility.h"
#include "op_bfd.h"
#include "sample_container.h"
#include "symbol_container.h"
#include "format_flags.h"

class string_filter;
class symbol_entry;
class sample_entry;

/**
 * Store multiple samples files belonging to the same profiling session.
 * This is the main container capable of holding the profiles for arbitrary
 * binary images and arbitrary profile classes.
 */
class profile_container : noncopyable {
public:
	/**
	 * Build an object to store information on samples. All parameters
	 * acts as hint for what you will request after recording samples and
	 * so allow optimizations during recording the information.
	 *
	 * @param debug_info If true line numbers and source files are recorded.
	 *
	 * @param need_details If true if we need to record all samples or to
	 * to record them at symbol level.
	 */
	profile_container(bool debug_info, bool need_details);

	~profile_container();
 
	/**
	 * add() - record symbols/samples in the underlying container
	 *
	 * @param profile the samples files container
	 * @param abfd the associated bfd object
	 * @param app_name the owning application name of sample
	 * @param pclass the profile class to add results for
	 *
	 * add() is an helper for delayed ctor. Take care you can't safely
	 * make any call to add after any other member function call.
	 * Obviously you can add only samples files which are coherent (same
	 * sampling rate, same events etc.)
	 */
	void add(profile_t const & profile, op_bfd const & abfd,
		 std::string const & app_name, size_t pclass);

	/// Find a symbol from its image_name, vma, return zero if no symbol
	/// for this image at this vma
	symbol_entry const * find_symbol(std::string const & image_name,
					 bfd_vma vma) const;

	/// Find a symbol from its filename, linenr, return zero if no symbol
	/// at this location
	symbol_entry const * find_symbol(debug_name_id filename,
					size_t linenr) const;

	/// Find a sample by its symbol, vma, return zero if there is no sample
	/// at this vma
	sample_entry const * find_sample(symbol_entry const * symbol,
					 bfd_vma vma) const;

	/// Find a symbol. Return NULL if not found.
	symbol_entry const * find(symbol_entry const & symbol) const;

	/// used for select_symbols()
	struct symbol_choice {
		symbol_choice()
			: hints(cf_none), threshold(0.0), match_image(false) {}

		/// hints filled in
		column_flags hints;
		/// percentage threshold
		double threshold;
		/// match the image name only
		bool match_image;
		/// owning image name
		std::string image_name;
	};

	/**
	 * select_symbols - create a set of symbols sorted by sample count
	 * @param choice  parameters to use/fill in when selecting
	 */
	symbol_collection const select_symbols(symbol_choice & choice) const;

	/// Like select_symbols for filename without allowing sort by vma.
	std::vector<debug_name_id> const select_filename(double threshold) const;

	/// return the total number of samples
	count_array_t samples_count() const;

	/// Get the samples count which belongs to filename. Return 0 if
	/// no samples found.
	count_array_t samples_count(debug_name_id filename_id) const;
	/// Get the samples count which belongs to filename, linenr. Return
	/// 0 if no samples found.
	count_array_t samples_count(debug_name_id filename,
			   size_t linenr) const;

	/// return an iterator to the first symbol
	symbol_container::symbols_t::iterator begin_symbol() const;
	/// return an iterator to the last symbol
	symbol_container::symbols_t::iterator end_symbol() const;

	/// return iterator to the first samples
	sample_container::samples_iterator begin() const;
	/// return iterator to the last samples
	sample_container::samples_iterator end() const;

	/// return iterator to the first samples for this symbol
	sample_container::samples_iterator begin(symbol_entry const *) const;
	/// return iterator to the last samples for this symbol
	sample_container::samples_iterator end(symbol_entry const *) const;

private:
	/// helper for add()
	void add_samples(op_bfd const & abfd, symbol_index_t sym_index,
	                 profile_t::iterator_pair const &,
	                 symbol_entry const * symbol, size_t pclass);

	/**
	 * create an unique artificial symbol for an offset range. The range
	 * is only a hint of the maximum size of the created symbol. We
	 * give to the symbol an unique name as ?image_file_name#order and
	 * a range up to the nearest of syms or for the whole range if no
	 * syms exist after the start offset. the end parameter is updated
	 * to reflect the symbol range.
	 *
	 * The rationale here is to try to create symbols for alignment between
	 * function as little as possible and to create meaningfull symbols
	 * for special case such image w/o symbol.
	 */
	std::string create_artificial_symbol(op_bfd const & abfd, u32 start,
	                                     u32 & end, size_t & order);

	/// The symbols collected by pp tools sorted by increased vma, provide
	/// also a sort order on samples count for each profile class
	scoped_ptr<symbol_container> symbols;
	/// The samples count collected by pp tools sorted by increased vma,
	/// provide also a sort order on (filename, linenr)
	scoped_ptr<sample_container> samples;
	/// build() must count samples count for each profile class so cache it
	/// here since user of profile_container often need it later.
	count_array_t total_count;

	/**
	 * Optimization hints for what information we are going to need,
	 * see the explanation in profile_container()	
	 */
	//@{
	bool debug_info;
	bool need_details;
	//@}
};

#endif /* !PROFILE_CONTAINER_H */
