/// @file octanetester.hpp
/// Classes for testing octane functions and compressors
///
/// @remarks
/// The OctaneTester class contains functions for testing compressors and
///  providing a commandline and interactive interface to octane functions.
///
/// @author mouser
/// @author Jibz
/// @date   2003.07.29
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// recursive header protection
#ifndef OctaneTesterH
#define OctaneTesterH
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// application includes
#include "../core/octane.hpp"
#include "../core/compressormanager.hpp"
// system includes
#include <string>
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
/// The OctaneTester class contains functions for testing compressors and
///  providing a commandline and interactive interface to octane functions.
class OctaneTester : public OctaneClass
{
protected:
	/// Currently selected Compressor class for interactive testing.
	OctaneCompressor *currentcompressorp;
public:
	/// Constructor
	OctaneTester();
	/// Destructor.
	~OctaneTester();
public:
	/// Show user help about how to use interactive commands within testloop; this is not to be customized for derived classes.
	void ShowHelp();
	/// Built in test loop that just asks user for input and compresses and decompresses in debug mode and lets user load and save files.
	void TestLoop();
	/// Parse an interactive command or a commandline statement
	/// @return true on successful parse of command
	bool ParseCommand(const std::string &inputstr);
	/// Run a stream (input file) full of commands.
	/// @return true on no errors encountered during processing.
	bool ExecuteCommandsFromStream(std::ifstream &from, bool quiet);
	/// Run a file full of commands.
	/// @return true on no errors encountered during processing.
	bool ExecuteCommandsFromFile(const std::string &filename, bool quiet);
protected:
	/// Grab a line from cin and return true on success
	/// @note this is necessary because of bugs in vc 6
	bool GrabLineFromConsole(std::string &line);
	/// List all registered compressors.
	void ListCompressors(bool briefmode);
	/// Select a compressor for subsequent operations; sets current compressorp in the process
	/// @return true on success.
	OctaneCompressor* SelectInstantiatedCompressor(const std::string &compressorname);
	/// Helper function during parsing, to verify that the current compressor is ready to compress and decompress
	/// show warning and return false if not.
	/// @return true if compressor is valid and ready
	bool CheckCompressorSelected(OctaneCompressor *compressorp);
	/// Helper function during parsing, to verify that the current compressor is ready to compress and decompress
	/// show warning and return false if not.
	/// @return true if compressor is valid and ready
	bool CheckCompressorReady(OctaneCompressor *compressorp);
	/// helper function to smartly add an extension to a file name, based on current compressor
	/// @return a new filename with extensions added to it if appropriate
	std::string MakeAssumedOutputFilename(const std::string &origname, const std::string &origext, const std::string &newext);
protected:
	/// Run the TestString command, to compress and then decompress a string and check for errors.
	/// @return true on success.
	bool RunCommand_TestString(std::string inputstring);
	/// Run the TestFile command, to compress and then decompress a file and check for errors.
	/// @return true on success.
	bool RunCommand_TestFile(std::string filename);
	/// Run the CreateCompressor command, to create a new instantiated compressor
	/// @return true on success.
	bool RunCommand_CreateCompressor(std::string compressorclassname,std::string compressorname, unsigned short guidnum);
	// some helper RunCommand functions
	/// Run the LoadCompressor command, to recall saved state space.
	/// @return true on success.
	bool RunCommand_LoadCompressor(std::string filename);
	/// Run the SaveCompressor command, to recall saved state space.
	/// @return true on success.
	bool RunCommand_SaveCompressor(std::string filename);
	/// Run the DeleteCompressor command, to delete an instantiated compressor
	/// @return true on success.
	bool RunCommand_DeleteCompressor(std::string compressoridstring);
	/// Run the MakeState command, to create state info (i.e. train on file).
	/// @return true on success.
	bool RunCommand_MakeState(std::string infilename);
	/// Run the Compress command, to compress a file and write result to another file
	/// @return true on success.
	bool RunCommand_Compress(std::string infilename,std::string outfilename, bool savedecompressstateinfo);
	/// Run the Decompress command, to decompress a file and write result to another file
	/// @return true on success.
	bool RunCommand_Decompress(std::string infilename,std::string outfilename, bool savedecompressstateinfo);
protected:
	/// Helper function, delete a file if it exists, or do nothing if not
	/// @return true on deletion of file or no file
	/// @todo this is not implemented yet
	bool DeleteAFile(std::string filename);
	/// Check two files and see if they are identical
	/// @return true if identical
	/// @todo do we need to do this more efficiently
	bool CheckFilesAreIdentical(std::string filename1,std::string filename2);
};

//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
