#include "CivSimulResDbHelper.h"
#include "CivPgDbConnection.h"
#include "CivTableFields.h"
#include "CivCommonUtils.h"

CivSimulResDbHelper::CivSimulResDbHelper(const std::string& uri)
{
	mConn = new CivPgDbConnection();
	mConn->connect(uri);

	NodeResultTableField tableFields;
	mNodeFields = 
	{
		tableFields.Number,	
		tableFields.dDemand,	
		tableFields.dPressure,
		tableFields.dQuality,
		tableFields.dHead,
		tableFields.dDate,
		tableFields.dInterval,
		tableFields.dModifyTime
	};

	// 
	PipeResultTableField pipeFields;
	mLinkFileds = {
		pipeFields.szNo,
		pipeFields.dFlow,
		pipeFields.dVelocity,
		pipeFields.dUnitHeadloss,
		pipeFields.dQuality,
		pipeFields.szStatus,
		pipeFields.dDate,
		pipeFields.dInterval,
		pipeFields.dModifyTime
	};
}

CivSimulResDbHelper::~CivSimulResDbHelper()
{
	mConn->disconnect();
	delete mConn;
}

bool CivSimulResDbHelper::insertNodes(const NodeResultItems& nodeitems)
{
	std::vector<std::vector<std::string>> vecVec;
	for (auto iter = nodeitems.begin(); iter != nodeitems.end(); iter++)
	{
		NodeResultItem nodeItem = iter->second;
		
		std::string sn = nodeItem.szNo;
		std::vector<std::string> vecRes =
		{
			 "\'"+sn+"\'",
			 std::to_string(nodeItem.dDemand),	
			 std::to_string(nodeItem.dPressure),
			 std::to_string(nodeItem.dQuality),
			 std::to_string(nodeItem.dHead),
			 "\'" + nodeItem.dDate + "\'",
			 "\'" + nodeItem.dTime + "\'",
			"\'" + CurrentTime + "\'"
		};
		vecVec.push_back(vecRes);	
	}

	if (!mConn->insertBulk(NODERESULTTABLE, mNodeFields, vecVec))
		return false;

	return true;
}

bool CivSimulResDbHelper::insertLinks(const LinkResultItems& linkMap)
{
	std::vector<std::vector<std::string>> vecVec;
	for (auto iter = linkMap.begin(); iter != linkMap.end(); iter++)
	{
		LinkResultItem linkItem = iter->second;
		std::string sn = linkItem.szNo;
		std::string status = linkItem.szStatus;
		std::vector<std::string> vecRes =
		{
			 "\'"+ sn +"\'",
			 std::to_string(linkItem.dFlow),
			 std::to_string(linkItem.dVelocity),
			 std::to_string(linkItem.dHeadloss),
			 std::to_string(linkItem.dQuality),
			 "\'"+ status + "\'",
			 "\'" + linkItem.dDate + "\'",
			 "\'" + linkItem.dTime + "\'",
			"\'" + CurrentTime + "\'"
		};
		vecVec.push_back(vecRes);
	}

	if (!mConn->insertBulk(PIPERESULTTABLE, mLinkFileds, vecVec))
		return false;

	return true;
}

bool CivSimulResDbHelper::insertTanks(const TankResultItems& tankMap)
{
	return true;
}

void CivSimulResDbHelper::getAllNodeCoords(NodeCoords& nodeCoords)
{
	std::vector<std::string> fileds = {
		"±¾µãºÅ","ºá×ø±ê","×Ý×ø±ê"
	};

	std::vector<std::map<std::string, std::string>> res;
	if (!mConn->query(PIPENODE, fileds, res))
		return;

	size_t total = res.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> nodeInfo = res[i];
		NodeCoord nodeCoord;

		std::string key = nodeInfo.find(fileds[0])->second;	
		nodeCoord.xCoord = nodeInfo.find(fileds[1])->second;
		nodeCoord.yCoord = nodeInfo.find(fileds[2])->second;

		nodeCoords[key] = nodeCoord;
	}

}

void CivSimulResDbHelper::getAllPipeCoords(PipeCoords& pipeCoords)
{
	std::vector<std::string> fileds = {
		"ST_X(ST_StartPoint(ST_GeometryN(geom,1))) as startx",
		"ST_Y(ST_StartPoint(ST_GeometryN(geom,1))) as starty", 
		"ST_X(ST_EndPoint(ST_GeometryN(geom,1))) as endX" ,
		"ST_Y(ST_EndPoint(ST_GeometryN(geom,1))) as endY",
		"±àºÅ"
	};

	std::vector<std::map<std::string, std::string>> res;
	if (!mConn->query(PIPELINE, fileds, res))
		return;

	size_t total = res.size();
	for (int i = 0; i < total; i++)
	{
		std::map<std::string, std::string> nodeInfo = res[i];
		PipeCoord pipeCoord;

		std::string key = nodeInfo.find("startx")->second;
		pipeCoord.startX = nodeInfo.find("startx")->second;
		pipeCoord.startY = nodeInfo.find("starty")->second;
		pipeCoord.endX = nodeInfo.find("endX")->second;
		pipeCoord.endY = nodeInfo.find("endY")->second;
		pipeCoords[key] = pipeCoord;
	}
}