#include "jsonobject.h"

#include <fstream>
#include <sstream>
#include <QDateTime>
#include <vector>
#include <QTranslator>
#include <QDebug>
#include <QApplication>
#include "json/cJSON.h"
const char* strProductFileName = "./cfgs/usct-product.json";
const char* strProductFileNameDefault = "./cfgs/usct-product";
JsonObject::JsonObject()
{
	loadcfg();

}
JsonObject::~JsonObject()
{
	savecfg();


}
void JsonObject::setJsonString(const char* catergory, const char* stringName, const char* stringValue, bool save)
{
	if (!loadcfg())
		return;

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, catergory);
	if (!first) return;

	cJSON* Item = cJSON_CreateString(stringValue);
	cJSON_ReplaceItemInObject(first, stringName, Item);
	if (save)
	{
		savecfg();
	}
}

char* JsonObject::getJsonString(const char* catergory, const char* stringName)
{
	if (!loadcfg())
		return nullptr;

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, catergory);
	if (!first) return nullptr;

	cJSON* second = cJSON_GetObjectItem(first, stringName);
	if (!second) return nullptr;
	return second->valuestring;

}
char* JsonObject::getArrayNode(const char* catergory, const char* stringName, int index, const char* id)
{
	if (!loadcfg())
		return nullptr;

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, catergory);
	if (!first) return nullptr;

	cJSON* second = cJSON_GetObjectItem(first, stringName);
	if (!second) return nullptr;

	cJSON* third = cJSON_GetArrayItem(second, index);
	if (!third) return nullptr;
	cJSON* fourth = cJSON_GetObjectItem(third, id);

	if (!fourth) return nullptr;
	return fourth->valuestring;
}

void JsonObject::setArrayNode(const char* catergory, const char* stringName, int index, const char* id, const char* stringValue)
{
	if (!loadcfg())
		return;

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, catergory);
	if (!first) return;

	cJSON* second = cJSON_GetObjectItem(first, stringName);
	if (!second) return;

	cJSON* third = cJSON_GetArrayItem(second, index);
	if (!third) return;
	cJSON* Item = cJSON_CreateString(stringValue);
	cJSON_ReplaceItemInObject(third, id, Item);
}


int JsonObject::getArraySize(const char* catergory, const char* stringName)
{
	if (!loadcfg())
		return 0;

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, catergory);
	if (!first) return 0;

	cJSON* second = cJSON_GetObjectItem(first, stringName);
	if (!second) return 0;
	return cJSON_GetArraySize(second);
}


void JsonObject::setDefaultUser(const QString& str)
{
	setJsonString("login", "defaultUser", str.toStdString().c_str());
}
QString JsonObject::defaultUser()
{
	char* str = getJsonString("login", "defaultUser");
	return QString(str);
}
QStringList JsonObject::protocals()
{
	if (!loadcfg())
		return QStringList();

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, "protocol");
	if (!first) return QStringList();

	cJSON* second = cJSON_GetObjectItem(first, "lists");
	std::string lans = second->valuestring;


	QString str = QString::fromLocal8Bit(QByteArray::fromRawData(lans.c_str(), lans.size()));
	return str.split(";");

}

QString JsonObject::defaultProtocal()
{
	char* str = getJsonString("protocol", "default");
	return QString(str);
}

void JsonObject::setDefaultProtocal(const QString& str)
{
	setJsonString("protocol", "default", str.toStdString().c_str());
}

QString JsonObject::defaultFilter()
{
	char* str = getJsonString("worklistfilter", "default");
	return QString(str);
}
void JsonObject::setDefaultFilter(const QString& str)
{
	setJsonString("worklistfilter", "default", str.toStdString().c_str());
}
QStringList JsonObject::worklistFilters()
{
	if (!loadcfg())
		return QStringList();

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, "worklistfilter");
	if (!first) return QStringList();

	cJSON* second = cJSON_GetObjectItem(first, "lists");


	std::string lans = second->valuestring;
	QString str = QString::fromLocal8Bit(QByteArray::fromRawData(lans.c_str(), lans.size()));
	return str.split(";");

}



QStringList JsonObject::language()
{
	if (!loadcfg())
		return QStringList();

	cJSON* first = cJSON_GetObjectItem((cJSON*)json_root, "general");
	if (!first) return QStringList();

	cJSON* second = cJSON_GetObjectItem(first, "language");
	if (!second) return QStringList();

	std::string lans = second->valuestring;
	QString str = QString::fromLocal8Bit(QByteArray::fromRawData(lans.c_str(), lans.size()));
	return str.split(";");

}

void JsonObject::setDefaultLanguage(const QString& str)
{
	setJsonString("general", "defaultlanguage", str.toStdString().c_str());
}

QString JsonObject::defaultLanguage()
{
	char* str = getJsonString("general", "defaultlanguage");
	return QString(str);
}

QString JsonObject::institutionName()
{
	char* str = getJsonString("general", "institutionName");
	return QString(str);
}
void JsonObject::setInstitutionName(const QString& str)
{
	setJsonString("general", "institutionName", str.toStdString().c_str());
}

QString JsonObject::institutionAddr()
{
	char* str = getJsonString("general", "institutionAddr");
	return QString(str);
}

void JsonObject::setInstitutionAddr(const QString& str)
{
	setJsonString("general", "institutionAddr", str.toStdString().c_str());
}

int JsonObject::lockerCount()
{
	char* str = getJsonString("general", "lockscreen");
	int interval = QString(str).toInt() * 1000;
	return interval;
}

QString JsonObject::lockScreenTimeout()
{
	char* str = getJsonString("general", "lockscreen");
	return QString(str);
}

void JsonObject::setLockScreenTimeout(const QString& str)
{
	setJsonString("general", "lockscreen", str.toStdString().c_str());
}

QString JsonObject::storageAlarmSize()
{
	char* str = getJsonString("storagepolicy", "mininum");
	return QString(str);
}

bool JsonObject::loadcfg()
{
	if (m_bLoaded)
		return true;

	std::ifstream inFile(strProductFileName);
	if (!inFile.is_open())
	{
		return loadcfgDefault();
	}
	std::stringstream ss;
	ss << inFile.rdbuf();
	std::string strJsonData = ss.str();
	json_root = cJSON_Parse(strJsonData.c_str());
	inFile.close();


	if (!json_root)
		return loadcfgDefault();

	m_bLoaded = true;
	return true;
}


bool JsonObject::loadcfgDefault()
{

	std::ifstream inFile(strProductFileNameDefault);
	if (!inFile.is_open())
	{
		return false;
	}
	std::stringstream ss;
	ss << inFile.rdbuf();
	std::string strJsonData = ss.str();
	json_root = cJSON_Parse(strJsonData.c_str());
	inFile.close();

	if (!json_root)
		return false;

	m_bLoaded = true;
	return true;
}

bool JsonObject::savecfg()
{
	if (!m_bLoaded)
		return false;

	std::ofstream outFile(strProductFileName);
	if (!outFile.is_open())
	{
		return false;
	}

	char* strJsonData = cJSON_Print((cJSON*)json_root);
	std::stringstream ss;
	ss << strJsonData;
	outFile << ss.rdbuf();
	outFile.close();
	m_bLoaded = false;
	return true;
}

host JsonObject::getServer(ServerType type)
{
	QString typeName;
	switch (type)
	{

	case JsonObject::WORKLIST:
		typeName = "worklist";
		break;
	case JsonObject::PACS:
		typeName = "pacs";
		break;
	case JsonObject::LOCAL:
		typeName = "address";
		break;
	case JsonObject::RECON:
		typeName = "recon";
		break;
	default:
		break;
	}
	host list;
	list.ae = QString(getJsonString(typeName.toStdString().c_str(), "ae"));
	list.ip = QString(getJsonString(typeName.toStdString().c_str(), "ip"));
	list.name = QString(getJsonString(typeName.toStdString().c_str(), "name"));
	list.port = QString(getJsonString(typeName.toStdString().c_str(), "port"));
	return list;
}

void JsonObject::setServer(ServerType type, const host& list)
{
	QString typeName;
	switch (type)
	{

	case JsonObject::WORKLIST:
		typeName = "worklist";
		break;
	case JsonObject::PACS:
		typeName = "pacs";
		break;
	case JsonObject::LOCAL:
		typeName = "address";
		break;
	case JsonObject::RECON:
		typeName = "recon";
		break;
	default:
		break;
	}
	setJsonString(typeName.toStdString().c_str(), "ae", list.ae.toStdString().c_str(), false);
	setJsonString(typeName.toStdString().c_str(), "ip", list.ip.toStdString().c_str(), false);
	setJsonString(typeName.toStdString().c_str(), "name", list.name.toStdString().c_str(), false);
	setJsonString(typeName.toStdString().c_str(), "port", list.port.toStdString().c_str(), false);

	savecfg();
}


QString JsonObject::interfaceName()
{
	return QString(getJsonString("address", "device"));
}

QString JsonObject::passWord()
{
	return tmp_psw;
}

void JsonObject::setPassword(const QString& pwd)
{

	tmp_psw = pwd;
}
void JsonObject::setInterfaceName(const QString& name)
{
	setJsonString("address", "device", name.toStdString().c_str());
}

bool JsonObject::isDHCP()
{
	QVariant tempValue = QString(getJsonString("address", "dhcp"));
	return tempValue.toBool();
}

void JsonObject::autoDHCP(bool ena)
{
	QString str = QVariant(ena).toString();
	setJsonString("address", "dhcp", str.toStdString().c_str());
}


IpAddr JsonObject::getDefaultIpAddr()
{
	IpAddr obj;
	//lhost.ip = IPConfig::getDeviceIP();
	obj.ip = QString(getJsonString("address", "ip"));
	obj.mask = QString(getJsonString("address", "mask"));
	return obj;
}

void JsonObject::setDefaultIpAddr(const IpAddr& addr)
{
	setJsonString("address", "ip", addr.ip.toStdString().c_str());
	setJsonString("address", "mask", addr.mask.toStdString().c_str());
}

QList<QStringList> JsonObject::getIpAddrList()
{

	QList<QStringList> obj;
	int size = getArraySize("address", "additional");
	for (int i = 0; i < size; i++)
	{
		QStringList temp;
		char* ip_str = getArrayNode("address", "additional", i, "ip");
		char* mask_str = getArrayNode("address", "additional", i, "netmask");

		temp << ip_str << mask_str;
		obj.push_back(temp);
	}
	return obj;
}

void JsonObject::setIpAddrList(const QList<QStringList>& list)
{
	for (int i = 0; i < list.size(); i++) {
		setArrayNode("address", "additional", i, "ip", list.at(i)[0].toStdString().c_str());
		setArrayNode("address", "additional", i, "netmask", list.at(i)[1].toStdString().c_str());
	}
	savecfg();
}

QString JsonObject::getDefaultGateway()
{
	return QString(getJsonString("routing", "defaultgateway"));
}

void JsonObject::setDefaultGateway(const QString& gw)
{
	setJsonString("routing", "defaultgateway", gw.toStdString().c_str());
}

QList<QStringList> JsonObject::getIpRouteList()
{
	QList<QStringList> obj;
	int size = getArraySize("routing", "routingtable");
	for (int i = 0; i < size; i++)
	{
		QStringList temp;
		char* des_str = getArrayNode("routing", "routingtable", i, "destination");
		char* gw_str = getArrayNode("routing", "routingtable", i, "gateway");
		char* nm_str = getArrayNode("routing", "routingtable", i, "netmask");

		temp << des_str << nm_str << gw_str;
		obj.push_back(temp);
	}
	return obj;
}

void JsonObject::setIpRouteList(const QList<QStringList>& list)
{
	for (int i = 0; i < list.size(); i++) {
		setArrayNode("routing", "routingtable", i, "destination", list.at(i)[0].toStdString().c_str());
		setArrayNode("routing", "routingtable", i, "netmask", list.at(i)[1].toStdString().c_str());
		setArrayNode("routing", "routingtable", i, "gateway", list.at(i)[2].toStdString().c_str());
	}
	savecfg();
}
