/**
 * @file format_output.h
 * outputting format for symbol lists
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#ifndef FORMAT_OUTPUT_H
#define FORMAT_OUTPUT_H

#include "config.h"

#include <string>
#include <map>
#include <iosfwd>

#include "format_flags.h"
#include "symbol.h"
#include "string_filter.h"
#include "xml_output.h"

class symbol_entry;
class sample_entry;
class callgraph_container;
class profile_container;
class diff_container;
class extra_images;
class op_bfd;

struct profile_classes;
// FIXME: should be passed to the derived class formatter ctor
extern profile_classes classes;

namespace format_output {

/// base class for formatter, handle common options to formatter
class formatter {
public:
	formatter(extra_images const & extra);
	virtual ~formatter();

	/// add a given column
	void add_format(format_flags flag);

	/// set the need_header boolean to false
	void show_header(bool);
	/// format for 64 bit wide VMAs
	void vma_format_64bit(bool);
	/// show long (full path) filenames
	void show_long_filenames(bool);
	/// use global count rather symbol count for details percent
	void show_global_percent(bool);

	/**
	 * Set the number of collected profile classes. Each class
	 * will output sample count and percentage in extra columns.
	 *
	 * This class assumes that the profile information has been
	 * populated with the right number of classes.
	 */
	void set_nr_classes(size_t nr_classes);

	/// output table header, implemented by calling the virtual function
	/// output_header_field()
	void output_header(std::ostream & out);

protected:
	struct counts_t {
		/// total sample count
		count_array_t total;
		/// samples so far
		count_array_t cumulated_samples;
		/// percentage so far
		count_array_t cumulated_percent;
		/// detailed percentage so far
		count_array_t cumulated_percent_details;
	};

	/// data passed for output
	struct field_datum {
		field_datum(symbol_entry const & sym,
		            sample_entry const & s,
			    size_t pc, counts_t & c,
			    extra_images const & extra, double d = 0.0)
			: symbol(sym), sample(s), pclass(pc),
			  counts(c), extra(extra), diff(d) {}
		symbol_entry const & symbol;
		sample_entry const & sample;
		size_t pclass;
		mutable counts_t & counts;
		extra_images const & extra;
		double diff;
	};
 
	/// format callback type
	typedef std::string (formatter::*fct_format)(field_datum const &);
 
	/** @name format functions.
	 * The set of formatting functions, used internally by output().
	 */
	//@{
	std::string format_vma(field_datum const &);
	std::string format_symb_name(field_datum const &);
	std::string format_image_name(field_datum const &);
	std::string format_app_name(field_datum const &);
	std::string format_linenr_info(field_datum const &);
	std::string format_nr_samples(field_datum const &);
	std::string format_nr_cumulated_samples(field_datum const &);
	std::string format_percent(field_datum const &);
	std::string format_cumulated_percent(field_datum const &);
	std::string format_percent_details(field_datum const &);
	std::string format_cumulated_percent_details(field_datum const &);
	std::string format_diff(field_datum const &);
	//@}
 
	/// decribe one field of the colummned output.
	struct field_description {
		field_description() {}
		field_description(std::size_t w, std::string h,
				  fct_format f)
			: width(w), header_name(h), formatter(f) {}
 
		std::size_t width;
		std::string header_name;
		fct_format formatter;
	};
 
	typedef std::map<format_flags, field_description> format_map_t;

	/// actually do output
	void do_output(std::ostream & out, symbol_entry const & symbol,
		      sample_entry const & sample, counts_t & c,
	              diff_array_t const & = diff_array_t(),
	              bool hide_immutable_field = false);
 
	/// returns the nr of char needed to pad this field
	size_t output_header_field(std::ostream & out, format_flags fl,
	                           size_t padding);

	/// returns the nr of char needed to pad this field
	size_t output_field(std::ostream & out, field_datum const & datum,
			   format_flags fl, size_t padding,
			   bool hide_immutable);
 
	/// stores functors for doing actual formatting
	format_map_t format_map;

	/// number of profile classes
	size_t nr_classes;

	/// total counts
	counts_t counts;

	/// formatting flags set
	format_flags flags;
	/// true if we need to format as 64 bits quantities
	bool vma_64;
	/// false if we use basename(filename) in output rather filename
	bool long_filenames;
	/// true if we need to show header before the first output
	bool need_header;
	/// bool if details percentage are relative to total count rather to
	/// symbol count
	bool global_percent;

	/// To retrieve the real image location, usefull when acting on
	/// an archive and for 2.6 kernel modules
	extra_images const & extra_found_images;
};
 

/// class to output in a columned format symbols and associated samples
class opreport_formatter : public formatter {
public:
	/// build a ready to use formatter
	opreport_formatter(profile_container const & profile);

	/** output a vector of symbols to out according to the output format
	 * specifier previously set by call(s) to add_format() */
	void output(std::ostream & out, symbol_collection const & syms);

	/// set the output_details boolean
	void show_details(bool);

private:
 
	/** output one symbol symb to out according to the output format
	 * specifier previously set by call(s) to add_format() */
	void output(std::ostream & out, symbol_entry const * symb);

	/// output details for the symbol
	void output_details(std::ostream & out, symbol_entry const * symb);
 
	/// container we work from
	profile_container const & profile;
 
	/// true if we need to show details for each symbols
	bool need_details;
};


/// class to output in a columned format caller/callee and associated samples
class cg_formatter : public formatter {
public:
	/// build a ready to use formatter
	cg_formatter(callgraph_container const & profile);

	/** output callgraph information according to the previously format
	 * specifier set by call(s) to add_format() */
	void output(std::ostream & out, symbol_collection const & syms);
};

/// class to output a columned format symbols plus diff values
class diff_formatter : public formatter {
public:
	/// build a ready to use formatter
	diff_formatter(diff_container const & profile,
		       extra_images const & extra);

	/**
	 * Output a vector of symbols to out according to the output
	 * format specifier previously set by call(s) to add_format()
	 */
	void output(std::ostream & out, diff_collection const & syms);

private:
	/// output a single symbol
	void output(std::ostream & out, diff_symbol const & sym);

};


/// class to output in XML format
class xml_formatter : public formatter {
public:
	/// build a ready to use formatter
	xml_formatter(profile_container const * profile,
		      symbol_collection & symbols, extra_images const & extra,
		      string_filter const & symbol_filter);

	// output body of XML output
	void output(std::ostream & out);

	/** output one symbol symb to out according to the output format
	 * specifier previously set by call(s) to add_format() */
	virtual void output_symbol(std::ostream & out,
		symbol_entry const * symb, size_t lo, size_t hi,
		bool is_module);

	/// output details for the symbol
	std::string output_symbol_details(symbol_entry const * symb,
		size_t & detail_index, size_t const lo, size_t const hi);

	/// set the output_details boolean
	void show_details(bool);

	// output SymbolData XML elements
	void output_symbol_data(std::ostream & out);

private:
	/// container we work from
	profile_container const * profile;
 
	// ordered collection of symbols associated with this profile
	symbol_collection & symbols;

	/// true if we need to show details for each symbols
	bool need_details;

	// count of DetailData items output so far
	size_t detail_count;

	/// with --details we need to reopen the bfd object for each symb to
	/// get it's contents, hence we store the filter used by the bfd ctor.
	string_filter const & symbol_filter;

	void output_sample_data(std::ostream & out,
		sample_entry const & sample, size_t count);

	/// output attribute in XML
	void output_attribute(std::ostream & out, field_datum const & datum,
			      format_flags fl, tag_t tag);

	/// Retrieve a bfd object for this symbol, reopening a new bfd object
	/// only if necessary
	bool get_bfd_object(symbol_entry const * symb, op_bfd * & abfd) const;

	void output_the_symbol_data(std::ostream & out,
		symbol_entry const * symb, op_bfd * & abfd);

	void output_cg_children(std::ostream & out,
		cg_symbol::children const cg_symb, op_bfd * & abfd);
};

// callgraph XML output version
class xml_cg_formatter : public xml_formatter {
public:
	/// build a ready to use formatter
	xml_cg_formatter(callgraph_container const & callgraph,
		symbol_collection & symbols, string_filter const & sf);

	/** output one symbol symb to out according to the output format
	 * specifier previously set by call(s) to add_format() */
	virtual void output_symbol(std::ostream & out,
		symbol_entry const * symb, size_t lo, size_t hi, bool is_module);

private:
	/// container we work from
	callgraph_container const & callgraph;

	void output_symbol_core(std::ostream & out,
		cg_symbol::children const cg_symb,
		std::string const selfname, std::string const qname,
		size_t lo, size_t hi, bool is_module, tag_t tag);
};

} // namespace format_output 


#endif /* !FORMAT_OUTPUT_H */
