#include "networkmanager.h"
#include "json/jsonobject.h"
#include <QProcess>
#include <QDebug>
#include <QRegularExpression>

//NetworkManager* NetworkManager::instance = nullptr;

//NetworkManager::NetworkManager(QObject* parent) : QObject(parent)
//{
//
//}


//NetworkManager* NetworkManager::Instance()
//{
//	if (nullptr == instance)
//	{
//		instance = new NetworkManager();
//	}
//	return instance;
//}


//void NetworkManager::qIfConfig(const localhost& lhost)
//{
//	QProcess* myProcess = new QProcess;
//	//QString cmd = QString("echo %1 | sudo -S ifconfig eth0 %2 up").;
//	QString cmd = QString("echo %1 | sudo -S ifconfig eth0 %2 netmask %3 up; sudo -S route del default dev eth0; \
//    sudo -S route add default gw %4").arg("klxts4047").arg(lhost.ip).arg(lhost.mask).arg(lhost.gateway);
//	QStringList args;
//	args << "-c" << cmd;
//	myProcess->start("/bin/sh", args);
//}
host NetworkManager::getLocalHost()
{
	return JsonObject::Instance()->getServer(JsonObject::LOCAL);
}

bool NetworkManager::setLocalHost(const host& h)
{
	JsonObject::Instance()->setServer(JsonObject::LOCAL, h);
	return true;
}
QString NetworkManager::interfaceName()
{
	return JsonObject::Instance()->interfaceName();
}
bool NetworkManager::isDHCP()
{
	return JsonObject::Instance()->isDHCP();
}
IpAddr NetworkManager::getDefaultIpAddr()
{
	return JsonObject::Instance()->getDefaultIpAddr();
}
QList<QStringList> NetworkManager::getIpAddrList()
{
	return JsonObject::Instance()->getIpAddrList();
}
QString NetworkManager::getDefaultGateway()
{
	return JsonObject::Instance()->getDefaultGateway();
}
QList<QStringList> NetworkManager::getIpRouteList()
{
	return JsonObject::Instance()->getIpRouteList();
}



bool NetworkManager::restart(QString& err_info)
{

	QProcess* myProcess = new QProcess;
	QString inface = JsonObject::Instance()->interfaceName();
	QString pwd = JsonObject::Instance()->passWord();
	QString cmd = QString("echo %1 | sudo -S rcnetwork restart %2").arg(pwd).arg(inface);
	QStringList args;
	args << "-c" << cmd;
	connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
	myProcess->start("/bin/sh", args);

	if (!myProcess->waitForFinished(60000)) {
		err_info.append("failed...\n");
		return false;
	}
	if (myProcess->exitCode() == 0) {
		err_info.append("suceess...\n");
		return  true;
	}
	else {
		err_info.append(myProcess->readAllStandardError());
		return  false;
	}
}

bool NetworkManager::setJsonDHCP(bool enable)
{
	JsonObject::Instance()->autoDHCP(enable);
	return true;
}
bool NetworkManager::setDefaultIpAddr(const IpAddr& addr, QString& err_info)
{

	QString ipaddr = NewExp(addr.ip, addr.mask);
	QProcess* myProcess = new QProcess;
	QString inface = JsonObject::Instance()->interfaceName();
	QString pwd = JsonObject::Instance()->passWord();
	QString cmd = QString("echo %1 | sudo -S ip addr add %2 dev %3").arg(pwd).arg(ipaddr).arg(inface);
	QStringList args;
	args << "-c" << cmd;
	connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
	myProcess->start("/bin/sh", args);

	if (!myProcess->waitForFinished()) {
		err_info.append("failed...\n");
		return false;
	}
	if (myProcess->exitCode() == 0) {
		JsonObject::Instance()->setDefaultIpAddr(addr);
		err_info.append("success...\n");
		return  true;
	}
	else {
		err_info.append(myProcess->readAllStandardError());
		return  false;
	}

}

bool NetworkManager::validate(const QString& addr)
{
	QRegularExpression ipFormat("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");
	QRegularExpressionMatch mre = ipFormat.match(addr);
	if (mre.hasMatch())
	{
		return true;
	}
	return false;
}

QString NetworkManager::NewExp(QString ip, QString mask)
{
	QStringList list = mask.split(".");
	int count = 0;
	for (QString str : list)
	{
		if (str == "255")
		{
			count++;
		}
	}
	QString temp = "";
	temp.append(ip).append("/").append(QString::number(count * 8));
	return temp;
}

bool NetworkManager::setIpAddrList(const QList<QStringList>& list, QString& err_info)
{

	QProcess* myProcess = new QProcess;
	QString inface = JsonObject::Instance()->interfaceName();
	QString pwd = JsonObject::Instance()->passWord();
	QString cmd = QString("echo %1 | ").arg(pwd);
	for (QStringList addr : list)
	{
		QString ipaddr = NewExp(addr[0], addr[1]);
		cmd.append(QString("sudo -S ip addr add %1 dev %2;").arg(ipaddr).arg(inface));
	}
	QStringList args;
	args << "-c" << cmd;
	connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
	myProcess->start("/bin/sh", args);

	if (!myProcess->waitForFinished()) {
		err_info.append("failed...\n");
		return false;
	}
	if (myProcess->exitCode() == 0) {
		JsonObject::Instance()->setIpAddrList(list);
		err_info.append("success...\n");
		return  true;
	}
	else {
		err_info.append(myProcess->readAllStandardError());
		return  false;
	}
}
bool NetworkManager::setDefaultGateway(const QString& gw, QString& err_info)
{

	QProcess* myProcess = new QProcess;
	QString pwd = JsonObject::Instance()->passWord();
	QString cmd = QString("echo %1 | sudo -S ip route replace default via %2").arg(pwd).arg(gw);
	QStringList args;
	args << "-c" << cmd;
	connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
	//qDebug()<<args;
	myProcess->start("/bin/sh", args);
	if (!myProcess->waitForFinished()) {
		err_info.append("failed...\n");
		return false;
	}
	if (myProcess->exitCode() == 0) {
		JsonObject::Instance()->setDefaultGateway(gw);
		err_info.append("success...\n");
		return  true;
	}
	else {
		err_info.append(myProcess->readAllStandardError());
		return  false;
	}

}

bool NetworkManager::checkPassWord(const QString& pwd, QString& err_info)
{

	QProcess* myProcess = new QProcess;
	//QString pwd = JsonObject::Instance()->passWord();
	QString cmd = QString("echo %1 | sudo -S -k whoami").arg(pwd);
	QStringList args;
	args << "-c" << cmd;
	connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
	//qDebug()<<args;
	myProcess->start("/bin/sh", args);
	if (!myProcess->waitForFinished()) {
		err_info.append("failed...\n");
		return false;
	}
	if (myProcess->exitCode() == 0) {
		err_info.append("success...\n");
		return  true;
	}
	else {
		err_info.append(myProcess->readAllStandardError());
		return  false;
	}

}


bool NetworkManager::setIpRouteList(const QList<QStringList>& list, QString& err_info)
{
	QProcess* myProcess = new QProcess;
	QString inface = JsonObject::Instance()->interfaceName();
	QString pwd = JsonObject::Instance()->passWord();
	QString cmd = QString("echo %1 | ").arg(pwd);
	for (QStringList route : list)
	{
		QString ipaddr = NewExp(route[0], route[1]);
		cmd.append(QString("sudo -S ip route replace %1 via %2 dev %3;").arg(ipaddr).arg(route[2]).arg(inface));
	}
	QStringList args;
	args << "-c" << cmd;
	connect(myProcess, SIGNAL(finished(int)), myProcess, SLOT(deleteLater()));
	myProcess->start("/bin/sh", args);
	if (!myProcess->waitForFinished()) {
		err_info.append("failed...\n");
		return false;
	}

	if (myProcess->exitCode() == 0) {
		JsonObject::Instance()->setIpRouteList(list);
		err_info.append("success...\n");
		return  true;
	}
	else {
		err_info.append(cmd);
		err_info.append("\n");
		err_info.append(myProcess->readAllStandardError());
		return  false;
	}
}
bool NetworkManager::testSetMode(QString& err_info)
{
	// autoDHCP(true);
	QString err1, err2, err3, err4;

	qDebug() << "DefaultIpAddr";
	const IpAddr& t1 = getDefaultIpAddr();

	bool ret1 = setDefaultIpAddr(t1, err1);
	err_info.append(err1);

	qDebug() << "DefaultGateway";

	const QString& t2 = getDefaultGateway();
	bool ret2 = setDefaultGateway(t2, err2);
	err_info.append(err2);

	qDebug() << "IpAddrList";
	const QList<QStringList>& t3 = getIpAddrList();
	bool ret3 = setIpAddrList(t3, err3);
	err_info.append(err3);

	qDebug() << "IpRouteList";
	const QList<QStringList>& t4 = getIpRouteList();
	bool ret4 = setIpRouteList(t4, err4);
	err_info.append(err4);

	return true;
}

void NetworkManager::testGetMode()
{
	qDebug() << "interfaceName()" << " : " << interfaceName();
	qDebug() << "isDHCP()" << " : " << isDHCP();

	IpAddr t1 = getDefaultIpAddr();
	qDebug() << "getDefaultIpAddr()" << " : " << t1.ip << " " << t1.mask;

	qDebug() << "getDefaultGateway()" << " : " << getDefaultGateway();

	qDebug() << "ggetIpAddrList()" << " : ";
	const QList<QStringList>& t2 = getIpAddrList();
	for (QStringList var : t2)
	{
		qDebug() << var[0] << " " << var[1];
	}
	qDebug() << "getDefaultIpAddr()" << " : " << t1.ip << " " << t1.mask;

	qDebug() << "getIpRouteList()" << " : ";
	const QList<QStringList>& t3 = getIpRouteList();
	for (QStringList var : t3)
	{
		qDebug() << var[0] << " " << var[1] << " " << var[2];
	}

}
