#include <iostream>
#include <string>
#include <cstdlib>
#include "Properties.h"
#include "util.h"

using namespace std;

void showmenu();
bool docommand(const string &command, Properties &props);


int main(int argc, char *argv[]) 
{
	const char *filename;
	Properties props;
	string command;
	bool finished;
	
	if(argc==1) {
		cout << "filename not specified, ";
		filename = "proptest.prop";
	} else if (argc==2) {
		filename = argv[1];
	} else {
		cerr << "usage: " << argv[0] << " [filename]\n";
		return 1;
	}

	cout << "using \"" << filename << "\"\n";
		
	try {
		props.load(filename);
	} catch(Properties::CannotOpen &err) {
		cout << "could not open " << err.filename() << ": "
		     <<	strerror(err.errno()) << endl;
	}

	showmenu();
	do {
		cout << "\nEnter a command: " << flush;
		getline(cin,command);
		finished = docommand(command, props);
	} while(!finished);
	
	return 0;
}

void showmenu() 
{
	cout << "Please enter one of the following commands:\n";
	cout << "-------------------------------------------\n";
	cout << "print   - display the entire property list\n";
	cout << "add     - add a property\n";
	cout << "get     - get the value of a property\n";
	cout << "remove  - remove a property\n";
	cout << "defined - is a property defined?\n";
	cout << "save    - save the property list to a file\n";
	cout << "help    - display this menu\n";
	cout << "quit    - quit this program\n";	
}


bool docommand(const string &command, Properties &props) 
{
	string cmd = command;
	string property;
	string value;
	
	stripws(cmd);
	lowercasify(cmd);
	
	if(cmd == "quit")
		return true;
	else if(cmd == "print")
		cout << props;
	else if(cmd == "add") {
		cout << "Add what property? " << flush;
		getline(cin, property);
		cout << "With what value? " << flush;
		getline(cin, value);
		
		try {
			props.addProperty(property, value);
			cout << property << " = " << value << " added\n";
		} catch (Properties::BadProperty &err) {
			cerr << "invalid property \"" << property << "\"\n";
		}
	} else if(cmd == "get") {
		cout << "Get the value for what property? " << flush;
		getline(cin, property);

		try {
			value = props.getValueFor(property);
			cout << property << " = " << value << endl;
		} catch(Properties::NotFound &err) {
			cerr << "property \"" << property << "\" not found\n";
		}
	} else if(cmd == "remove") {
		cout << "Remove what property? " << flush;
		getline(cin, property);

		try {
			value = props.remove(property);
			cout << property << " = " << value << " removed\n";
		} catch(Properties::NotFound &err) {
			cerr << "property \"" << property << "\" not found\n";
		}
	} else if(cmd == "defined") {
		cout << "Test definition of what property? " << flush;
		getline(cin, property);

		cout << "property \"" << property << "\" "
		     << (props.isDefined(property) ? "found" : "not found")
		     << endl;
	} else if(cmd == "save") {
		string filename;
		
		cout << "Save as? " << flush;
		getline(cin, filename);

		try {
			props.save(filename.c_str());
		} catch(Properties::CannotOpen &err) {
			cout << "could not open " << err.filename() << ": "
			     <<	strerror(err.errno()) << endl;
		}
	} else if(cmd == "help") {
		showmenu();
	} else if(!cmd.empty()) {
		cerr << "Invalid command: \"" << command << "\"\n";
		cerr << "Type \"help\" for a menu\n";
	}
		
	return false;
}
