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

#include "CivHydrSimulation.h"
#include "CivTrackingAnalysis.h"
#include "CivProjSimulation.h"
#include "JsonParseObject.h"
#include "CivOptSchedEngine.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;
}