/*
 * ASTInspector.h
 *
 *  Created on: Dec 17, 2012
 *      Author: att
 */

#ifndef ASTINSPECTOR_H_
#define ASTINSPECTOR_H_

#include <map>
#include "Visitor.h"
#include "AST/AllTypesOfASTNodes.h"
/**
 * ASTInspector is a class which is used to inspect nodes of AST.
 * It's very useful. It provides user information about structure of the AST, how
 * particular nodes are built, and some other information, more statistical such as,
 * how many particular nodes is in tree. Thanks to depth awareness output can
 * be well formatted. Every node is visited in different manner.
 */

class ASTInspector: public Visitor {
public:
	ASTInspector();
	unsigned int how_many_visits() { return number_of_visits; }
	/**
	 * For instance: how_many_occurences_of("BasicExpression") return how many times ASTInspector has encountered
	 * BasicExpression node.
	 */
	unsigned int how_many_occurences_of(std::string type);

	/**
	 * get_report() returns inspection report. To get report, you first have to
	 * visit some tree, using "visit" function.
	 */
	std::string get_report() { return this->inspection_report; }

	virtual ~ASTInspector();

	/**
	 * forget_everything() erases all data which ASTInspector got during inspection.
	 * It's useful when we want to use ASTInspector for more trees than one, and data from previous
	 * shouldn't mix with data from current one.
	 */
	void forget_everything();

	void visit(Visitable * node);


private:
	unsigned int number_of_visits;
	typedef unsigned int NumberOfNodes;
	std::map<std::string, NumberOfNodes> occurences;
	std::string inspection_report;
	unsigned int depth_level;
	std::string compute_indent();

	/**
	 * write_report is an internal method used for
	 * generating report in incremental way, using
	 * notes from current visits and formatting it on right depth_level.
	 */
	void write_report(std::string visit_notes);

	void visit(ProgramNode * node);
	void visit(ImportStatement * import);
	void visit(ConstantExpression * node);
	void visit(BasicExpression * node);
	void visit(UnaryExpression * node);
	void visit(PostfixExpression * node);
	void visit(WhileNode * node);
	void visit(BasicStatement * node);
	void visit(DeclarationStatement * node);
	void visit(Assignment * node);
	void visit(IfNode * node);
	void visit(IncorrectExpression * node);
	void visit(RepeatStatement * node);
	void visit(VariableExpression * node);



};

#endif /* ASTINSPECTOR_H_ */
