/***************************************************************************
 *   Copyright (C) 2005 by Christof Donat   *
 *   cdonat@gmx.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 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 General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <boost/filesystem/exception.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>

#include <iostream>
#include <map>
#include <fstream>

#include <errno.h>

#include "logger.h"

namespace Logger {

const int FATAL   = 1;
const int ERROR   = 2;
const int WARNING = 4;
const int DEBUG   = 8;
const int XML     = 16;
int levels[6] = { 1, 3, 7, 15, 23, 31 };
int level = 1;

std::map<int,std::string> messages;

void setLevel(int newlevel) {
	level = newlevel;
	if( level > 5 ) level = 5;
	if( level < 0 ) level = 0;
}
void incrementLevel() {
	level++;
	if( level > 5 ) level = 5;
}
void decrementLevel() {
	level--;
	if( level < 0 ) level = 0;
}

void log(int type, const std::string text) {
	int bitmask = levels[level];

	if( type & bitmask )
		std::cerr << text << std::endl;
}

void insertMessages(std::string filename) {
	std::ifstream file(filename.c_str(),std::ios::in);
	if( !file ) return;

	char input[1024];

	while(!file.eof()) {
		bzero(input,1024);
		file.getline(input,1023);
		char *c = input;
		// ignore whitespace at beginning of line
		while( *c == ' ' || *c == '\t' ) c++;
		// lines that dont't begin with a digit are ignored
		if( *c < '0' || *c > '9' ) continue;
		char *i = c;
		while( *c >= '0' && *c <= '9' ) c++;
		char *j = c;
		while( *c == ' ' || *c == '\t' ) c++;
		// the digit istn't followed by a '=' -> ignore this line
		if( *c != '=' ) continue;
		// separate number from content
		*j = '\0';
		std::string number(i);
		std::string formatstring(c+1);
		messages[boost::lexical_cast<int>(number)] = boost::trim_copy(formatstring);
	}
}

void loadMessages() {
	std::string lang = getenv("LANG");
	std::string priv = getenv("HOME");

	try {
		boost::filesystem::path general("/etc/hsadminc.messages");
		if( boost::filesystem::exists(general) && !boost::filesystem::is_directory(general) )
			insertMessages(general.native());
	} catch(boost::filesystem::filesystem_error) {}

	try {
		boost::filesystem::path generalLang("/etc/hsadminc.messages."+lang);
		if( boost::filesystem::exists(generalLang) && !boost::filesystem::is_directory(generalLang) )
			insertMessages(generalLang.native());
	} catch(boost::filesystem::filesystem_error) {}

	try {
		boost::filesystem::path p( priv + "/.hsadmin.messages" );
		if( boost::filesystem::exists(p) && !boost::filesystem::is_directory(p) )
			insertMessages(p.native());
	} catch(boost::filesystem::filesystem_error) {}

	try {
		boost::filesystem::path pLang( priv + "/.hsadmin.messages."+lang );
		if( boost::filesystem::exists(pLang) && !boost::filesystem::is_directory(pLang) )
			insertMessages(pLang.native());
	} catch(boost::filesystem::filesystem_error) {}
}

std::string getErrnoMessage(int e) {
	if( messages.empty() ) loadMessages();
	std::map<int,std::string>::iterator i = messages.find(e);
	if( i != messages.end() ) return i->second;
	else return std::string("");
}

std::string getMessageFormatString(const message msg) {
	return getErrnoMessage((int)msg);
}

}
