/*
* Copyright 2008, 2009, 2010 Free Software Foundation, Inc.
* Copyright 2010 Kestrel Signal Processing, Inc.
* Copyright 2011, 2012 Range Networks, Inc.
*
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


#include "Configuration.h"
#include "Logger.h"
#include <fstream>
#include <iostream>
#include <string.h>

#ifdef DEBUG_CONFIG
#define	debugLogEarly gLogEarly
#else
#define	debugLogEarly(x,y,z)
#endif


using namespace std;

char gCmdName[20] = {0}; // Use a char* to avoid avoid static initialization of string, and race at startup.

static const char* createConfigTable = {
	"CREATE TABLE IF NOT EXISTS CONFIG ("
		"KEYSTRING TEXT UNIQUE NOT NULL, "
		"VALUESTRING TEXT, "
		"STATIC INTEGER DEFAULT 0, "
		"OPTIONAL INTEGER DEFAULT 0, "
		"COMMENTS TEXT DEFAULT ''"
	")"
};

static std::string replaceAll(const std::string input, const std::string search, const std::string replace)
{
	std::string output = input;
	size_t index = 0;

	while (true) {
		index = output.find(search, index);
		if (index == std::string::npos) {
			break;
		}

		output.replace(index, replace.length(), replace);
		index += replace.length();
	}

	return output;
}


float ConfigurationRecord::floatNumber() const
{
	float val;
	sscanf(mValue.c_str(),"%f",&val);
	return val;
}


ConfigurationTable::ConfigurationTable(const char* filename, const char *wCmdName, ConfigurationKeyMap wSchema)
{
	gLogEarly(LOG_INFO, "opening configuration table from path %s", filename);
	// Connect to the database.
	int rc = sqlite3_open(filename,&mDB);
	// (pat) When I used malloc here, sqlite3 sporadically crashes.
	if (wCmdName) {
		strncpy(gCmdName,wCmdName,18);
		gCmdName[18] = 0;
		strcat(gCmdName,":");
	}
	if (rc) {
		gLogEarly(LOG_EMERG, "cannot open configuration database at %s, error message: %s", filename, sqlite3_errmsg(mDB));
		sqlite3_close(mDB);
		mDB = NULL;
		return;
	}
	// Create the table, if needed.
	if (!sqlite3_command(mDB,createConfigTable)) {
		gLogEarly(LOG_EMERG, "cannot create configuration table in database at %s, error message: %s", filename, sqlite3_errmsg(mDB));
	}

	// Build CommonLibs schema
	ConfigurationKey *tmp;
	tmp = new ConfigurationKey("Log.File","",
		"",
		ConfigurationKey::DEVELOPER,
		ConfigurationKey::FILEPATH_OPT,// audited
		"",
		false,
		"Path to use for textfile based logging.  "
			"By default, this feature is disabled.  "
			"To enable, specify an absolute path to the file you wish to use, eg: /tmp/my-debug.log.  "
			"To disable again, execute \"unconfig Log.File\"."
	);
	mSchema[tmp->getName()] = *tmp;
	delete tmp;

	tmp = new ConfigurationKey("Log.Level","NOTICE",
		"",
		ConfigurationKey::CUSTOMER,
		ConfigurationKey::CHOICE,
		"EMERG|EMERGENCY - report serious faults associated with service failure or hardware damage,"
			"ALERT|ALERT - report likely service disruption caused by misconfiguration or poor connectivity,"
			"CRIT|CRITICAL - report anomalous events that are likely to degrade service,"
			"ERR|ERROR - report internal errors of the software that may result in degradation of service in unusual circumstances,"
			"WARNING|WARNING - report anomalous events that may indicate a degradation of normal service,"
			"NOTICE|NOTICE - report anomalous events that probably do not affect service but may be of interest to network operators,"
			"INFO|INFORMATION - report normal events,"
			"DEBUG|DEBUG - only for use by developers and will degrade system performance",
		false,
		"Default logging level when no other level is defined for a file."
	);
	mSchema[tmp->getName()] = *tmp;
	delete tmp;

	// Add application specific schema
	mSchema.insert(wSchema.begin(), wSchema.end());

	// Init the cross checking callback to something predictable
	mCrossCheck = NULL;
}

string ConfigurationTable::getDefaultSQL(const std::string& program, const std::string& version)
{
	stringstream ss;
	ConfigurationKeyMap::iterator mp;

	ss << "--" << endl;
	ss << "-- This file was generated using: " << program << " --gensql" << endl;
	ss << "-- binary version: " << version << endl;
	ss << "--" << endl;
	ss << "-- Future changes should not be put in this file directly but" << endl;
	ss << "-- rather in the program's ConfigurationKey schema." << endl;
	ss << "--" << endl;
	ss << "PRAGMA foreign_keys=OFF;" << endl;
	ss << "BEGIN TRANSACTION;" << endl;
	ss << "CREATE TABLE CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');" << endl;

	mp = mSchema.begin();
	while (mp != mSchema.end()) {
		ss << "INSERT INTO \"CONFIG\" VALUES(";
			// name
			ss << "'" << mp->first << "',";
			// default
			ss << "'" << mp->second.getDefaultValue() << "',";
			// static
			if (mp->second.isStatic()) {
				ss << "1";
			} else {
				ss << "0";
			}
			ss << ",";
			// optional
			ss << "0,";
			// description
			ss << "'";
			if (mp->second.getType() == ConfigurationKey::BOOLEAN) {
				ss << "1=enabled, 0=disabled - ";
			}
			ss << mp->second.getDescription();
			if (mp->second.isStatic()) {
				ss << "  Static.";
			}
			ss << "'";
		ss << ");" << endl;
		mp++;
	}

	ss << "COMMIT;" << endl;
	ss << endl;

	return ss.str();
}

string ConfigurationTable::getTeX(const std::string& program, const std::string& version)
{
	stringstream ss;
	ConfigurationKeyMap::iterator mp;

	ss << "% START AUTO-GENERATED CONTENT" << endl;
	ss << "% -- these sections were generated using: " << program << " --gentex" << endl;
	ss << "% -- binary version: " << version << endl;

	ss << "\\subsection{Customer Site Parameters}" << endl;
	ss << "These parameters must be changed to fit your site." << endl;
	ss << "\\begin{itemize}" << endl;
	mp = mSchema.begin();
	while (mp != mSchema.end()) {
		if (mp->second.getVisibility() == ConfigurationKey::CUSTOMERSITE) {
			ss << "	\\item ";
				// name
				ss << mp->first << " -- ";
				// description
				ss << mp->second.getDescription();
			ss << endl;
		}
		mp++;
	}
	ss << "\\end{itemize}" << endl;
	ss << endl;

	ss << "\\subsection{Customer Tuneable Parameters}" << endl;
	ss << "These parameters can be changed to optimize your site." << endl;
	ss << "\\begin{itemize}" << endl;
	mp = mSchema.begin();
	while (mp != mSchema.end()) {
		if (mp->second.getVisibility() != ConfigurationKey::CUSTOMERSITE &&
			(
				mp->second.getVisibility() == ConfigurationKey::CUSTOMER ||
				mp->second.getVisibility() == ConfigurationKey::CUSTOMERTUNE ||
				mp->second.getVisibility() == ConfigurationKey::CUSTOMERWARN
			)) {
			ss << "	\\item ";
				// name
				ss << mp->first << " -- ";
				// description
				ss << mp->second.getDescription();
			ss << endl;
		}
		mp++;
	}
	ss << "\\end{itemize}" << endl;
	ss << endl;

	ss << "\\subsection{Developer/Factory Parameters}" << endl;
	ss << "These parameters should only be changed by when developing new code." << endl;
	ss << "\\begin{itemize}" << endl;
	mp = mSchema.begin();
	while (mp != mSchema.end()) {
		if (mp->second.getVisibility() == ConfigurationKey::FACTORY ||
			mp->second.getVisibility() == ConfigurationKey::DEVELOPER) {
			ss << "	\\item ";
				// name
				ss << mp->first << " -- ";
				// description
				ss << mp->second.getDescription();
			ss << endl;
		}
		mp++;
	}
	ss << "\\end{itemize}" << endl;
	ss << "% END AUTO-GENERATED CONTENT" << endl;
	ss << endl;

	string tmp = replaceAll(ss.str(), "^", "\\^");
	return replaceAll(tmp, "_", "\\_");
}

bool ConfigurationTable::defines(const string& key)
{
	try {
		ScopedLock lock(mLock);
		return lookup(key).defined();
	} catch (ConfigurationTableKeyNotFound) {
		debugLogEarly(LOG_ALERT, "configuration parameter %s not found", key.c_str());
		return false;
	}
}

bool ConfigurationTable::keyDefinedInSchema(const std::string& name)
{
	return mSchema.find(name) == mSchema.end() ? false : true;
}

bool ConfigurationTable::isValidValue(const std::string& name, const std::string& val) {
	bool ret = false;

	ConfigurationKey key = mSchema[name];

	switch (key.getType()) {
		case ConfigurationKey::BOOLEAN: {
			if (val == "1" || val == "0") {
				ret = true;
			}
			break;
		}

		case ConfigurationKey::CHOICE_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::CHOICE: {
			int startPos = -1;
			uint endPos = 0;

			std::string tmp = key.getValidValues();

			do {
				startPos++;
				if ((endPos = tmp.find('|', startPos)) != std::string::npos) {
					if (val == tmp.substr(startPos, endPos-startPos)) {
						ret = true;
						break;
					}
				} else {
					if (val == tmp.substr(startPos, tmp.find(',', startPos)-startPos)) {
						ret = true;
						break;
					}
				}

			} while ((startPos = tmp.find(',', startPos)) != (int)std::string::npos);
			break;
		}

		case ConfigurationKey::CIDR_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::CIDR: {
			uint delimiter;
			std::string ip;
			int cidr = -1;

			delimiter = val.find('/');
			if (delimiter != std::string::npos) {
				ip = val.substr(0, delimiter);
				std::stringstream(val.substr(delimiter+1)) >> cidr;
				if (ConfigurationKey::isValidIP(ip) && 0 <= cidr && cidr <= 32) {
					ret = true;
				}
			}
			break;
		}

		case ConfigurationKey::FILEPATH_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::FILEPATH: {
			regex_t r;
			const char* expression = "^[a-zA-Z0-9/_.-]+$";
			int result = regcomp(&r, expression, REG_EXTENDED);
			if (result) {
				char msg[256];
				regerror(result,&r,msg,255);
				break;//abort();
			}
			if (regexec(&r, val.c_str(), 0, NULL, 0)==0) {
				ret = true;
			}
			regfree(&r);
			break;
		}

		case ConfigurationKey::IPADDRESS_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::IPADDRESS: {
			ret = ConfigurationKey::isValidIP(val);
			break;
		}

		case ConfigurationKey::IPANDPORT: {
			uint delimiter;
			std::string ip;
			int port = -1;

			delimiter = val.find(':');
			if (delimiter != std::string::npos) {
				ip = val.substr(0, delimiter);
				std::stringstream(val.substr(delimiter+1)) >> port;
				if (ConfigurationKey::isValidIP(ip) && 1 <= port && port <= 65535) {
					ret = true;
				}
			}
			break;
		}

		case ConfigurationKey::MIPADDRESS_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::MIPADDRESS: {
			int startPos = -1;
			uint endPos = 0;

			do {
				startPos++;
				endPos = val.find(' ', startPos);
				if (ConfigurationKey::isValidIP(val.substr(startPos, endPos-startPos))) {
					ret = true;
				} else {
					ret = false;
					break;
				}

			} while ((startPos = endPos) != (int)std::string::npos);
			break;
		}

		case ConfigurationKey::PORT_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::PORT: {
			int intVal;

			std::stringstream(val) >> intVal;

			if (1 <= intVal && intVal <= 65535) {
				ret = true;
			}
			break;
		}

		case ConfigurationKey::REGEX_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::REGEX: {
			regex_t r;
			const char* expression = val.c_str();
			int result = regcomp(&r, expression, REG_EXTENDED);
			if (result) {
				char msg[256];
				regerror(result,&r,msg,255);
			} else {
				ret = true;
			}
			regfree(&r);
			break;
		}

		case ConfigurationKey::STRING_OPT: {
			if (val.length() == 0) {
				ret = true;
				break;
			}
		}
		case ConfigurationKey::STRING: {
			regex_t r;
			const char* expression = key.getValidValues().c_str();
			int result = regcomp(&r, expression, REG_EXTENDED);
			if (result) {
				char msg[256];
				regerror(result,&r,msg,255);
				break;//abort();
			}
			if (regexec(&r, val.c_str(), 0, NULL, 0)==0) {
				ret = true;
			}
			regfree(&r);
			break;
		}

		case ConfigurationKey::VALRANGE: {
			regex_t r;
			int result;
			if (key.getValidValues().find('.') != std::string::npos) {
				result = regcomp(&r, "^[0-9.-]+$", REG_EXTENDED);
			} else {
				result = regcomp(&r, "^[0-9-]+$", REG_EXTENDED);
			}
			if (result) {
				char msg[256];
				regerror(result,&r,msg,255);
				break;//abort();
			}
			if (regexec(&r, val.c_str(), 0, NULL, 0)!=0) {
				ret = false;
			} else if (key.getValidValues().find('.') != std::string::npos) {
				ret = ConfigurationKey::isInValRange<float>(key, val, false);
			} else {
				ret = ConfigurationKey::isInValRange<int>(key, val, true);
			}

			regfree(&r);
			break;
		}
	}

	return ret;
}

ConfigurationKeyMap ConfigurationTable::getSimilarKeys(const std::string& snippet) {
	ConfigurationKeyMap tmp;

	ConfigurationKeyMap::const_iterator mp = mSchema.begin();
	while (mp != mSchema.end()) {
		if (mp->first.find(snippet) != std::string::npos) {
			tmp[mp->first] = mp->second;
		}
		mp++;
	}

	return tmp;
}

const ConfigurationRecord& ConfigurationTable::lookup(const string& key)
{
	assert(mDB);
	checkCacheAge();
	// We assume the caller holds mLock.
	// So it is OK to return a reference into the cache.

	// Check the cache.
	// This is cheap.
	ConfigurationMap::const_iterator where = mCache.find(key);
	if (where!=mCache.end()) {
		if (where->second.defined()) return where->second;
		throw ConfigurationTableKeyNotFound(key);
	}

	// Check the database.
	// This is more expensive.
	char *value = NULL;
	sqlite3_single_lookup(mDB,"CONFIG",
			"KEYSTRING",key.c_str(),"VALUESTRING",value);

	// value found, cache the result
	if (value) {
		mCache[key] = ConfigurationRecord(value);
	// key definition found, cache the default
	} else if (keyDefinedInSchema(key)) {
		mCache[key] = ConfigurationRecord(mSchema[key].getDefaultValue());
	// total miss, cache the error
	} else {
		mCache[key] = ConfigurationRecord(false);
		throw ConfigurationTableKeyNotFound(key);
	}

	free(value);

	// Leave mLock locked.  The caller holds it still.
	return mCache[key];
}



bool ConfigurationTable::isStatic(const string& key)
{
	if (keyDefinedInSchema(key)) {
		return mSchema[key].isStatic();
	} else {
		return false;
	}
}




string ConfigurationTable::getStr(const string& key)
{
	// We need the lock because rec is a reference into the cache.
	try {
		ScopedLock lock(mLock);
		return lookup(key).value();
	} catch (ConfigurationTableKeyNotFound) {
		// Raise an alert and re-throw the exception.
		debugLogEarly(LOG_ALERT, "configuration parameter %s has no defined value", key.c_str());
		throw ConfigurationTableKeyNotFound(key);
	}
}


bool ConfigurationTable::getBool(const string& key)
{
	try {
		return getNum(key) != 0;
	} catch (ConfigurationTableKeyNotFound) {
		// Raise an alert and re-throw the exception.
		debugLogEarly(LOG_ALERT, "configuration parameter %s has no defined value", key.c_str());
		throw ConfigurationTableKeyNotFound(key);
	}
}


long ConfigurationTable::getNum(const string& key)
{
	// We need the lock because rec is a reference into the cache.
	try {
		ScopedLock lock(mLock);
		return lookup(key).number();
	} catch (ConfigurationTableKeyNotFound) {
		// Raise an alert and re-throw the exception.
		debugLogEarly(LOG_ALERT, "configuration parameter %s has no defined value", key.c_str());
		throw ConfigurationTableKeyNotFound(key);
	}
}


float ConfigurationTable::getFloat(const string& key)
{
	try {
		ScopedLock lock(mLock);
		return lookup(key).floatNumber();
	} catch (ConfigurationTableKeyNotFound) {
		// Raise an alert and re-throw the exception.
		debugLogEarly(LOG_ALERT, "configuration parameter %s has no defined value", key.c_str());
		throw ConfigurationTableKeyNotFound(key);
	}
}

std::vector<string> ConfigurationTable::getVectorOfStrings(const string& key)
{
	// Look up the string.
	char *line=NULL;
	try {
		ScopedLock lock(mLock);
		const ConfigurationRecord& rec = lookup(key);
		line = strdup(rec.value().c_str());
	} catch (ConfigurationTableKeyNotFound) {
		// Raise an alert and re-throw the exception.
		debugLogEarly(LOG_ALERT, "configuration parameter %s has no defined value", key.c_str());
		throw ConfigurationTableKeyNotFound(key);
	}

	assert(line);
	char *lp = line;
	
	// Parse the string.
	std::vector<string> retVal;
	while (lp) {
		while (*lp==' ') lp++;
		if (*lp == '\0') break;
		char *tp = strsep(&lp," ");
		if (!tp) break;
		retVal.push_back(tp);
	}
	free(line);
	return retVal;
}


std::vector<unsigned> ConfigurationTable::getVector(const string& key)
{
	// Look up the string.
	char *line=NULL;
	try {
		ScopedLock lock(mLock);
		const ConfigurationRecord& rec = lookup(key);
		line = strdup(rec.value().c_str());
	} catch (ConfigurationTableKeyNotFound) {
		// Raise an alert and re-throw the exception.
		debugLogEarly(LOG_ALERT, "configuration parameter %s has no defined value", key.c_str());
		throw ConfigurationTableKeyNotFound(key);
	}

	assert(line);
	char *lp = line;

	// Parse the string.
	std::vector<unsigned> retVal;
	while (lp) {
		// Watch for multiple or trailing spaces.
		while (*lp==' ') lp++;
		if (*lp=='\0') break;
		retVal.push_back(strtol(lp,NULL,0));
		strsep(&lp," ");
	}
	free(line);
	return retVal;
}


bool ConfigurationTable::remove(const string& key)
{
	assert(mDB);

	ScopedLock lock(mLock);
	// Clear the cache entry and the database.
	ConfigurationMap::iterator where = mCache.find(key);
	if (where!=mCache.end()) mCache.erase(where);
	// Really remove it.
	string cmd = "DELETE FROM CONFIG WHERE KEYSTRING=='"+key+"'";
	return sqlite3_command(mDB,cmd.c_str());
}



void ConfigurationTable::find(const string& pat, ostream& os) const
{
	// Prepare the statement.
	string cmd = "SELECT KEYSTRING,VALUESTRING FROM CONFIG WHERE KEYSTRING LIKE \"%" + pat + "%\"";
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(mDB,&stmt,cmd.c_str())) return;
	// Read the result.
	int src = sqlite3_run_query(mDB,stmt);
	while (src==SQLITE_ROW) {
		const char* value = (const char*)sqlite3_column_text(stmt,1);
		os << sqlite3_column_text(stmt,0) << " ";
		int len = 0;
		if (value) {
			len = strlen(value);
		}
		if (len && value) os << value << endl;
		else os << "(disabled)" << endl;
		src = sqlite3_run_query(mDB,stmt);
	}
	sqlite3_finalize(stmt);
}


ConfigurationRecordMap ConfigurationTable::getAllPairs() const
{
	ConfigurationRecordMap tmp;

	// Prepare the statement.
	string cmd = "SELECT KEYSTRING,VALUESTRING FROM CONFIG";
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(mDB,&stmt,cmd.c_str())) return tmp;
	// Read the result.
	int src = sqlite3_run_query(mDB,stmt);
	while (src==SQLITE_ROW) {
		const char* key = (const char*)sqlite3_column_text(stmt,0);
		const char* value = (const char*)sqlite3_column_text(stmt,1);
		if (key && value) {
			tmp[string(key)] = ConfigurationRecord(value);
		} else if (key && !value) {
			tmp[string(key)] = ConfigurationRecord(false);
		}
		src = sqlite3_run_query(mDB,stmt);
	}
	sqlite3_finalize(stmt);

	return tmp;
}

bool ConfigurationTable::set(const string& key, const string& value)
{
	assert(mDB);
	ScopedLock lock(mLock);
	string cmd = "INSERT OR REPLACE INTO CONFIG (KEYSTRING,VALUESTRING,OPTIONAL) VALUES (\"" + key + "\",\"" + value + "\",1)";
	bool success = sqlite3_command(mDB,cmd.c_str());
	// Cache the result.
	if (success) mCache[key] = ConfigurationRecord(value);
	return success;
}

bool ConfigurationTable::set(const string& key, long value)
{
	char buffer[30];
	sprintf(buffer,"%ld",value);
	return set(key,buffer);
}


bool ConfigurationTable::set(const string& key)
{
	assert(mDB);
	ScopedLock lock(mLock);
	string cmd = "INSERT OR REPLACE INTO CONFIG (KEYSTRING,VALUESTRING,OPTIONAL) VALUES (\"" + key + "\",NULL,1)";
	bool success = sqlite3_command(mDB,cmd.c_str());
	if (success) mCache[key] = ConfigurationRecord(true);
	return success;
}


void ConfigurationTable::checkCacheAge()
{
	// mLock is set by caller 
	static time_t timeOfLastPurge = 0;
	time_t now = time(NULL);
	// purge every 3 seconds
	// purge period cannot be configuration parameter
	if (now - timeOfLastPurge < 3) return;
	timeOfLastPurge = now;
	// this is purge() without the lock
	ConfigurationMap::iterator mp = mCache.begin();
	while (mp != mCache.end()) {
		ConfigurationMap::iterator prev = mp;
		mp++;
		mCache.erase(prev);
	}
}


void ConfigurationTable::purge()
{
	ScopedLock lock(mLock);
	ConfigurationMap::iterator mp = mCache.begin();
	while (mp != mCache.end()) {
		ConfigurationMap::iterator prev = mp;
		mp++;
		mCache.erase(prev);
	}
}


void ConfigurationTable::setUpdateHook(void(*func)(void *,int ,char const *,char const *,sqlite3_int64))
{
	assert(mDB);
	sqlite3_update_hook(mDB,func,NULL);
}


void ConfigurationTable::setCrossCheckHook(vector<string> (*wCrossCheck)(const string&))
{
	mCrossCheck = wCrossCheck;
}


vector<string> ConfigurationTable::crossCheck(const string& key) {
	vector<string> ret;

	if (mCrossCheck != NULL) {
		ret = mCrossCheck(key);
	}

	return ret;
}

void HashString::computeHash()
{
	// FIXME -- Someone needs to review this hash function.
	const char* cstr = c_str();
	mHash = 0;
	for (unsigned i=0; i<size(); i++) {
		mHash = mHash ^ (mHash >> 32);
		mHash = mHash*127 + cstr[i];
	}
}


void SimpleKeyValue::addItem(const char* pair_orig)
{
	char *pair = strdup(pair_orig);
	char *key = pair;
	char *mark = strchr(pair,'=');
	if (!mark) return;
	*mark = '\0';
	char *value = mark+1;
	mMap[key] = value;
	free(pair);
}



const char* SimpleKeyValue::get(const char* key) const
{
	HashStringMap::const_iterator p = mMap.find(key);
	if (p==mMap.end()) return NULL;
	return p->second.c_str();
}


void SimpleKeyValue::addItems(const char* pairs_orig)
{
	char *pairs = strdup(pairs_orig);
	char *thisPair;
	while ((thisPair=strsep(&pairs," "))!=NULL) {
		addItem(thisPair);
	}
	free(pairs);
}


bool ConfigurationKey::isValidIP(const std::string& ip) {
	struct sockaddr_in sa;
	return inet_pton(AF_INET, ip.c_str(), &(sa.sin_addr)) != 0;
}


void ConfigurationKey::getMinMaxStepping(const ConfigurationKey &key, std::string &min, std::string &max, std::string &stepping) {
	uint delimiter;
	int startPos;
	uint endPos;

	std::string tmp = key.getValidValues();
	stepping = "1";

	// grab steps if they're defined
	startPos = tmp.find('(');
	if (startPos != (int)std::string::npos) {
		endPos = tmp.find(')');
		stepping = tmp.substr(startPos+1, endPos-startPos-1);
		tmp = tmp.substr(0, startPos);
	}
	startPos = 0;

	delimiter = tmp.find(':', startPos);
	min = tmp.substr(startPos, delimiter-startPos);
	max = tmp.substr(delimiter+1, tmp.find(',', delimiter)-delimiter-1);
}


template<class T> bool ConfigurationKey::isInValRange(const ConfigurationKey &key, const std::string& val, const bool isInteger) {
	bool ret = false;

	T convVal;
	T min;
	T max;
	T steps;
	std::string strMin;
	std::string strMax;
	std::string strSteps;

	std::stringstream(val) >> convVal;

	ConfigurationKey::getMinMaxStepping(key, strMin, strMax, strSteps);
	std::stringstream(strMin) >> min;
	std::stringstream(strMax) >> max;
	std::stringstream(strSteps) >> steps;

	// TODO : only ranges checked, steps not enforced
	if (isInteger) {
		if (val.find('.') == std::string::npos && min <= convVal && convVal <= max) {
			ret = true;
		}
	} else {
		if (min <= convVal && convVal <= max) {
			ret = true;
		}
	}

	return ret;
}

const std::string ConfigurationKey::getARFCNsString() {
	stringstream ss;
	int i;
	float downlink;
	float uplink;

	// 128:251 GSM850
	downlink = 869.2;
	uplink = 824.2;
	for (i = 128; i <= 251; i++) {
		ss << i << "|GSM850 #" << i << " : " << downlink << " MHz downlink / " << uplink << " MHz uplink,";
		downlink += 0.2;
		uplink += 0.2;
	}

	// 1:124 PGSM900
	downlink = 935.2;
	uplink = 890.2;
	for (i = 1; i <= 124; i++) {
		ss << i << "|PGSM900 #" << i << " : " << downlink << " MHz downlink / " << uplink << " MHz uplink,";
		downlink += 0.2;
		uplink += 0.2;
	}

	// 512:885 DCS1800
	downlink = 1805.2;
	uplink = 1710.2;
	for (i = 512; i <= 885; i++) {
		ss << i << "|DCS1800 #" << i << " : " << downlink << " MHz downlink / " << uplink << " MHz uplink,";
		downlink += 0.2;
		uplink += 0.2;
	}

	// 512:810 PCS1900
	downlink = 1930.2;
	uplink = 1850.2;
	for (i = 512; i <= 810; i++) {
		ss << i << "|PCS1900 #" << i << " : " << downlink << " MHz downlink / " << uplink << " MHz uplink,";
		downlink += 0.2;
		uplink += 0.2;
	}

	ss << endl;

	return ss.str();
}

const std::string ConfigurationKey::visibilityLevelToString(const ConfigurationKey::VisibilityLevel& visibility) {
	std::string ret = "UNKNOWN ERROR";

	switch (visibility) {
		case ConfigurationKey::CUSTOMER:
			ret = "customer - can be freely changed by the customer without any detriment to their system";
			break;
		case ConfigurationKey::CUSTOMERSITE:
			ret = "customer site - these values are different for each BTS and should not be left default";
			break;
		case ConfigurationKey::CUSTOMERTUNE:
			ret = "customer tune - should only be changed to tune an installation to better suit the physical environment or MS usage pattern";
			break;
		case ConfigurationKey::CUSTOMERWARN:
			ret = "customer warn - a warning will be presented and confirmation required before changing this sensitive setting";
			break;
		case ConfigurationKey::DEVELOPER:
			ret = "developer - should only be changed by developers to debug/optimize the implementation";
			break;
		case ConfigurationKey::FACTORY:
			ret = "factory - set once at the factory, should never be changed";
			break;
	}

	return ret;
}

const std::string ConfigurationKey::typeToString(const ConfigurationKey::Type& type) {
	std::string ret = "UNKNOWN ERROR";

	switch (type) {
		case BOOLEAN:
			ret = "boolean";
			break;
		case CHOICE_OPT:
			ret = "multiple choice (optional)";
			break;
		case CHOICE:
			ret = "multiple choice";
			break;
		case CIDR_OPT:
			ret = "CIDR notation (optional)";
			break;
		case CIDR:
			ret = "CIDR notation";
			break;
		case FILEPATH_OPT:
			ret = "file path (optional)";
			break;
		case FILEPATH:
			ret = "file path";
			break;
		case IPADDRESS_OPT:
			ret = "IP address (optional)";
			break;
		case IPADDRESS:
			ret = "IP address";
			break;
		case IPANDPORT:
			ret = "IP address and port";
			break;
		case MIPADDRESS_OPT:
			ret = "space-separated list of IP addresses (optional)";
			break;
		case MIPADDRESS:
			ret = "space-separated list of IP addresses";
			break;
		case PORT_OPT:
			ret = "IP port (optional)";
			break;
		case PORT:
			ret = "IP port";
			break;
		case REGEX_OPT:
			ret = "regular expression (optional)";
			break;
		case REGEX:
			ret = "regular expression";
			break;
		case STRING_OPT:
			ret = "string (optional)";
			break;
		case STRING:
			ret = "string";
			break;
		case VALRANGE:
			ret = "value range";
			break;
	}

	return ret;
}

void ConfigurationKey::printKey(const ConfigurationKey &key, const std::string& currentValue, ostream& os) {
	os << key.getName() << " ";
	if (!currentValue.length()) {
		os << "(disabled)";
	} else {
		os << currentValue;
	}
	if (currentValue.compare(key.getDefaultValue()) == 0) {
		os << "     [default]";
	}
	os << endl;
}

void ConfigurationKey::printDescription(const ConfigurationKey &key, ostream& os) {
	std::string tmp;

	os << " - description:      " << key.getDescription() << std::endl;
	if (key.getUnits().length()) {
		os << " - units:            " << key.getUnits() << std::endl;
	}
	os << " - type:             " << ConfigurationKey::typeToString(key.getType()) << std::endl;
	if (key.getDefaultValue().length()) {
		os << " - default value:    " << key.getDefaultValue() << std::endl;
	}
	os << " - visibility level: " << ConfigurationKey::visibilityLevelToString(key.getVisibility()) << std::endl;
	os << " - static:           " << key.isStatic() << std::endl;

	tmp = key.getValidValues();
	if (key.getType() == ConfigurationKey::VALRANGE) {
		int startPos = tmp.find('(');
		uint delimiter = 0;
		if (startPos != (int)std::string::npos) {
			tmp = tmp.substr(0, startPos);
		}
		startPos = -1;

		do {
			startPos++;
			delimiter = tmp.find(':', startPos);
			os << " - valid values:     " << "from " << tmp.substr(startPos, delimiter-startPos) << " to "
				<< tmp.substr(delimiter+1, tmp.find(',', delimiter)-delimiter-1) << std::endl;

		} while ((startPos = tmp.find(',', startPos)) != (int)std::string::npos);

	} else if (key.getType() == ConfigurationKey::CHOICE) {
		int startPos = -1;
		uint endPos = 0;

		do {
			startPos++;
			if ((endPos = tmp.find('|', startPos)) != std::string::npos) {
				os << " - valid values:     " << tmp.substr(startPos, endPos-startPos);
				os << " = " << tmp.substr(endPos+1, tmp.find(',', endPos)-endPos-1) << std::endl;
			} else {
				os << " - valid values:     " << tmp.substr(startPos, tmp.find(',', startPos)-startPos) << std::endl;
			}

		} while ((startPos = tmp.find(',', startPos)) != (int)std::string::npos);

	} else if (key.getType() == ConfigurationKey::BOOLEAN) {
		os << " - valid values:     0 = disabled" << std::endl;
		os << " - valid values:     1 = enabled" << std::endl;

	} else if (key.getType() == ConfigurationKey::STRING) {
		os << " - valid val regex:  " << tmp << std::endl;

	} else if (key.getValidValues().length()) {
		os << " - raw valid values: " << tmp << std::endl;
	}
}


// vim: ts=4 sw=4
