#include "messagelog.h"
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QtCore/QDateTime>
#include <QtCore/QVariant>
#include <QtCore/QFile>
#include <QtCore/QCoreApplication>
#include <signal.h>

#ifdef Q_OS_WIN
#include <windows.h>
#endif

MessageLog::MessageLog()  {
	//database = new QSqlDatabase;
	//QSQLiteDriver *driver = new QSQLiteDriver;
	//database = QSqlDatabase::addDatabase(driver);
	database = QSqlDatabase::addDatabase("QSQLITE");
}

bool MessageLog::open(const QString &path) {
	if(!database.isValid()) return false;
	database.setDatabaseName(path);
	//qDebug("is open ? %d", database.isOpen());
	if(database.isOpen()) return false;
	QByteArray lock_path_ba = path.toLocal8Bit();
	lock_file = new QFile(QString("%1.lock").arg(path));
	if(lock_file->exists()) {
		if(!lock_file->open(QFile::ReadOnly)) {
			qWarning("MessageLog::open: lock file '%s' exist but can't open", lock_path_ba.data());
			return false;
		}
		QByteArray content = lock_file->readLine();
		lock_file->close();
		if(!content.isEmpty()) {
			int pid = content.toInt();
#ifndef Q_OS_WIN
			if(pid && kill(pid, 0) == 0) {
#else
			HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
			// The Windows API design is shit!
			if(handle != INVALID_HANDLE_VALUE && handle) {
				CloseHandle(handle);
#endif
				qWarning("MessageLog::open: database file is locked by process %d via lock file '%s'", pid, lock_path_ba.data());
				return false;
			}
		}
		//lock_file->remove();
	}
	if(!lock_file->open(QFile::WriteOnly | QFile::Truncate)) {
		qWarning("MessageLog::open: cannot open lock file '%s'", lock_path_ba.data());
		return false;
	}
	if(lock_file->write(QByteArray::number(QCoreApplication::applicationPid())) < 0) {
		QByteArray error_msg = lock_file->errorString().toLocal8Bit();
		qWarning("MessageLog::open: cannot write to lock file '%s', %s", lock_path_ba.data(), error_msg.data());
		lock_file->close();
		return false;
	}
	lock_file->close();
	QFile db_file(path);
	bool need_chmod = !db_file.exists();
	if(!database.open()) return false;
	if(need_chmod) db_file.setPermissions(QFile::ReadUser | QFile::WriteUser);
	QString sql_create_table("CREATE TABLE IF NOT EXISTS messages ("
				 "id INTEGER PRIMARY KEY AUTOINCREMENT,"
				 "receive_time DATETIME,"
				 "time DATETIME,"
				 "from_user CHAR(32),"
				 "to_user CHAR(32),"
				 "type INT8,"
				 "message TEXT );");
	if(!QSqlQuery(sql_create_table, database).exec()) {
		QByteArray ba = path.toLocal8Bit();
		qWarning("MessageLog::open: failed to run create table SQL in database %s, giving up open", ba.data());
		database.close();
		return false;
	}
	return true;
}

void MessageLog::close() {
	if(!database.isOpen()) return;
	database.close();
	lock_file->remove();
}

bool MessageLog::append_message(const QDateTime &dt, const QString &from_user, const QString &to_user, quint8 type, const QByteArray &message) {
	QSqlQuery query(database);
	query.prepare("INSERT INTO messages (receive_time,time,from_user,to_user,type,message) VALUES (?,?,?,?,?,?);");
	query.bindValue(0, QDateTime::currentDateTime());
	query.bindValue(1, dt);
	query.bindValue(2, from_user);
	query.bindValue(3, to_user);
	query.bindValue(4, type);
	query.bindValue(5, message);
	return query.exec();
}
