#include "CivHydrFuncInter.h"
#include "CivSysLog.h"

#include "CivHydrSimulation.h"
#include "CivTrackingAnalysis.h"
#include "CivProjSimulation.h"
#include "JsonParseObject.h"
#include "CivOptSchedEngine.h"
#include "CivInpConvertor.h"
#include "CivDynamicCompute.h"
#include "CivPumpHelper.h"
#include "CivHydrTableHelper.h"
#include "StringUtils.h"

bool PANDANALYSIS_API hdyrSimulation(char* uri)
{
    std::string uriStr = uri;
    if (uriStr.empty())
        return false;

    CivHydrSimulation simulation(uri);
    return simulation.hdyrSimulation();
}

bool PANDANALYSIS_API qualitySimulation(char* uri)
{
    std::string uriStr = uri;
    if (uriStr.empty())
        return false;

    CivHydrSimulation simulation(uri);
    return simulation.qualitySimulation();
}

bool PANDANALYSIS_API trackingSimulation(char* uri, char* sN, int hours, char* result)
{
    std::string uriStr = uri;
    std::string sNStr = sN;

    // 先清空掉输出空间的
    memset(result, 0, sizeof(result) / sizeof(char));

    if (uriStr.empty() || sNStr.empty())
        return false;


    CivHydrSimulation simulation(uri);

    std::string res;
    if (!simulation.trackingSimulation(sN, hours, res))
        return false;

    strcpy(result, res.c_str());

    return  true;
}

bool PANDANALYSIS_API upstreamTracking(char* uri, char* sn, char* result)
{
    std::string uriStr = uri;
    std::string snStr = sn;

    if (uriStr.empty() || snStr.empty())
        return false;

    CivTrackingAnalysis track(uri);
    if (!track.createGraphFrom())
    {
        return false;
    }

    std::string jsonResult;
    if (!track.upstreamTracking(sn, jsonResult))
        return false;

    strcpy(result, jsonResult.c_str());

    return true;
}

bool PANDANALYSIS_API downstreamTracking(char* uri, char* sn, char* result)
{
    std::string uriStr = uri;
    std::string snStr = sn;

    if (uriStr.empty() || snStr.empty())
        return false;

    CivTrackingAnalysis track(uri);
    track.createGraphFrom();

    std::string jsonResult;
    if (!track.downstreamTracking(sn, jsonResult))
        return false;

    strcpy(result, jsonResult.c_str());
    return true;
}

bool PANDANALYSIS_API waterSupplyScopeAnalysis(char* uri, char* sn, char* result)
{
    
    return true;
}

bool PANDANALYSIS_API projSimulation(char* uri, char* projCode, char* time)
{
    std::string uriStr = uri;
    std::string projCodeStr = projCode;

    if (uriStr.empty() || projCodeStr.empty())
        return false;

    CivProjSimulation projSimulation(uri);

    if (!projSimulation.simulationProj(projCode, time))
        return false;

    return true;
}

bool PANDANALYSIS_API optimalSchedulingSimulation(char* uri, char* condition, int timeInterval, char* result)
{
    // 类型装换
    string uriStr = uri;
    string conditionStr = condition;
    
    if (uriStr.empty() || conditionStr.empty())
        return false;

    // 解析输入的字符串转换位对应容器数据
    JsonParseObject jsonObj;
    jsonObj.parse(conditionStr);

    // 解析条件参数，监测点的最带和最小值的映射
    map<string, vector<double>> condiTionMap;
    jsonObj.read(condiTionMap);
    jsonObj.clear();

    vector<string> monitorsVec;
    map<string, vector<double>>::iterator iter = condiTionMap.begin();

    map<string, double> maxMonitorVals;
    map<string, double> minMonitorVals;
    for (; iter != condiTionMap.end(); iter++)
    {
        string monitorSz = iter->first;
        monitorsVec.push_back(monitorSz);

        vector<double> monitorValVec = iter->second;
        if (monitorValVec.size() < 2)
            continue;

        minMonitorVals.insert(pair<string, double>(monitorSz, monitorValVec[0]));
        maxMonitorVals.insert(pair<string, double>(monitorSz, monitorValVec[1]));
    }


    // 优化调度客户端
    CivOptSchedEngine schedEngine(uriStr);
    schedEngine.setMonitors(monitorsVec);
    schedEngine.setMaxMonitorVals(maxMonitorVals);
    schedEngine.setMinMonitorVals(minMonitorVals);
    schedEngine.setSchedulingPeriod(timeInterval);

    if (!schedEngine.optimalScheduling(timeInterval))
        return false;

    std::string resultStr;
    schedEngine.schedulingResultToJson(resultStr);

    // 复制
    strcpy(result, resultStr.c_str());

    return true;
}

bool PANDANALYSIS_API residualChlorineAnalysis(char* uri, char* startTime, char* endTime, char* conditionMap,char* error)
{
    std::string uriStr = uri;
    std::string conditionMapStr = conditionMap;
    std::string startTimeStr = startTime;
    std::string endTimeStr = endTime;

    std::string result;
    struct ConditionStruct conditionStruct;

    JsonParseObject jsonParseObj;
    jsonParseObj.parse(conditionMapStr);

    jsonParseObj.read(conditionStruct);
    if (conditionStruct.mCondMap.size() <= 0)
    {
        result = "输入的json字符串有错误！";
        return false;
    }
    // 转inp文件
    CivInpConvertor conventor(uriStr);
    std::string inpFile = conventor.convertResidualInp();

    // 调用计算接口
    CivDynamicCompute dynCompute;
    if (!dynCompute.openFile(inpFile))
    {
        result = "打开inp文件失败";
        return false;
    }

    dynCompute.setStartTime(startTimeStr);
    dynCompute.setEndTime(endTimeStr);
    dynCompute.updateQuality(conditionStruct.mCondMap);

    // 解析开始和结束时间
    int start = StringUtils::parseInt(startTimeStr);
    int end = StringUtils::parseInt(endTimeStr);

    // 开始执行加u三
    if (!dynCompute.compute(start, end))
    {
        result = "计算失败！";
        return false;
    }

    // 计算成功后，读取计算值更新到数据库
    std::map<std::string, std::map<std::string, float>> resultMap;
    dynCompute.simulResult(resultMap);

    if (resultMap.size() <= 0)
    {
        result = "出现位置错误，，没有获取到模拟值！";
        return false;
    }

    // 链接数据库，更新数据
    CivPumpHelper pumpHelper(uriStr);

    if (!pumpHelper.updateDatas("节点模拟值", resultMap))
    {
        result = "存储数据失败!";
        return false;
    }

    // 
    return true;
}

bool PANDANALYSIS_API netTopo(char* uri, char* error)
{
    CivHydrTableHelper hydrHelper(uri);
    return hydrHelper.mainTain();
}