#pragma once
#include <string>
#include<memory>
#include <vector>
#include <map>

using namespace std;
class CivSchedulingCompute;

/**
  优化调度客户端
*/
class CivOptSchedEngine
{
public:
	explicit CivOptSchedEngine(const string& uri);

	bool optimalScheduling(int time);

	// 设置监测点
	void updateMonitorsVals(const map<string,double>& monitorVals);

	/**
	*@brief 监测点的编号
	* @param [monitor] 监测点的编号
	*/
	void setMonitors(const vector<string>& monitor);

	/**
	*@brief 设置需要调度的时段，范围为0-24
	* @param [time] 调度的时段
	*/
	void setSchedulingPeriod(int time) { mPeriod = time; }

	void setMinMonitorVals(const map<string, double>& monitorVals) 
	{ mMinMonitorVals = monitorVals; }

	void setMaxMonitorVals(const map<string, double>& monitorVals) 
	{ mMaxMonitorVals = monitorVals; }

	/**
	*@brief 将计算结果转换为json字符串
	*@param [out] json 输出结果的字符串
	*/
	void schedulingResultToJson(string& json);

	/**
	* @brief 序列化到inp文件
	* @param [inpName] inp文件名
	*/
	void serializeToInpFile(string& inpName);

protected:
	/**
	*@brief 调度之前的一些初始化操作
	*/
	bool beginCompute();

	/**
	*@brief 调度之后的一些收尾工作，清理
	*/
	void endCompute();

private:
	// 编码与状态的映射
	map<int, string> mStatusBit;

	// 选出的最优组合
	map<string, float> mPumpBestSpeed;

	// 监测点编码
	vector<string> mMonitorsVec;

	// 本点好到code的映射
	map<string, string> mMonitorsSnMap;

	// 实时计算的当前监测点的值
	map<string,double> mCurrentMonitorVals;

	// 监测点压力的界限值
	map<string, double> mMaxMonitorVals;
	map<string, double> mMinMonitorVals;

	map<string, double> mBforeSchedulingResults;
	map<string, double> mAfterSchedulingResults;

	// 水泵编号，索引位代表
	vector<string> mPumpVec;
	map<string, string> mPumpSzMap;

	// 数据连接地址
	string mUri;

	// 调度的那个时段
	int mPeriod;

	// 初始中群大小
	int popsize;

	// 变异率
	double mMutRate;

	// 交叉率
	double mCrossRate;

	//基因编码长度
	int mGenLength;

	std::shared_ptr< CivSchedulingCompute> mSchedulingCompute;

	// 针对浮点数编码
	double mLeftPoint;
	double mRightPoint;
};

	
