#define _CRT_SECURE_NO_WARNINGS
#include "epm_handler_common.h"
#include <vector>
#include <string>
#include "ocilib.h"
#include <map>
#include <string>
#include <iostream>
#include <tccore/item.h>
#include <curl/curl.h>
#include <regex>
#include <fstream>
#include <chrono>
#include <ctime>
#include <memory>
#include <cstring>
#include <sstream>
#include <algorithm>
#include <exception> 
#define ITK_err 919821
using namespace std;


char* concat(char** s, int size) {
	int length = 0;
	for (int i = 0; i < size; i++) {
		length += strlen(s[i]);
	}
	char* result = new char[length + 1];
	int index = 0;
	for (int i = 0; i < size; i++) {
		int len = strlen(s[i]);
		memcpy(result + index, s[i], len);
		index += len;
	}
	result[length] = '\0';
	return result;
}

// 移除字符串两端的空白字符
string trim(string str) {
	str.erase(0, str.find_first_not_of(" \n\r\t"));
	str.erase(str.find_last_not_of(" \n\r\t") + 1);
	return str;
}
// 将字符串按照某个字符分割成多个子串
vector<string> split(string str, char delimiter) {
	vector<string> tokens;
	stringstream ss(str);
	string token;
	while (getline(ss, token, delimiter)) {
		tokens.push_back(trim(token));
	}
	return tokens;
}
// 解析JSON字符串中的字符串值
string parseString(string str) {
	str.erase(0, 1); // 移除开头的双引号
	str.erase(str.size() - 1); // 移除结尾的双引号
	return str;
}
// 解析JSON字符串中的整数值
int64_t parseInteger(string str) {
	return stoll(trim(str));
}
void morechat(char **& values,char *& result) {
	std::string values_str;
	for (int i = 0; *(values + i) != nullptr; i++) { // 使用双重指针访问数组元素
		if (i > 0) {
			values_str += ", ";
		}
		values_str += *(values + i);
	}
	result = new char[values_str.size() + 1];
	std::strcpy(result, values_str.c_str());
	std::cout << result << std::endl;
	delete[] result;
	delete[] values; // 记得释放 char** 类型的指针数组
}

static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
	((std::string*)userp)->append((char*)contents, size * nmemb);
	return size * nmemb;
}
size_t writeFunction(void* ptr, size_t size, size_t nmemb, std::string* data) {
	data->append((char*)ptr, size * nmemb);
	return size * nmemb;
}

void Split(string strArg, string spliter, vector<string> &ans)
{
	ans.clear();
	size_t index0 = 0;
	string one_arg;
	if (strArg.find_first_not_of(' ') == string::npos)
		strArg = "";
	while (strArg.size() > 0)
	{
		index0 = strArg.find_first_of(spliter);
		if (index0 != string::npos)
		{
			one_arg = strArg.substr(0, index0);
			strArg = strArg.substr(index0 + 1);
			ans.push_back(one_arg);
		}
		else
		{
			ans.push_back(strArg);
			break;
		}
	}
}

int RB_PLM2LIMS_JCSY(EPM_action_message_t msg)
{
	auto logFile = std::make_unique<std::ofstream>("D:\\TCTOLIMS\\output.log", std::ios_base::app);
	logFile->is_open();
	auto now = std::chrono::system_clock::now();
	std::time_t time = std::chrono::system_clock::to_time_t(now);
	std::string timeStr = std::ctime(&time);
	*logFile << "[" << timeStr.substr(0, timeStr.size() - 1) << "] ";
	*logFile << "=========================传递TC检测分析委托单信息至LIMS===================" << std::endl;
	POM_AM__set_application_bypass(true); // 开旁路
	*logFile << "=========================开旁路===================" << std::endl;
	printf("=========================传递TC检测分析委托单信息至LIMS===================\n");
	int ifail = ITK_ok;
	int  attachments_num = 0;
	tag_t  rootTask = NULLTAG, *attachments = NULLTAG;
	//获取任务对象
	EPM_ask_root_task(msg.task, &rootTask);
	//获取任务目标对象
	EPM_ask_attachments(rootTask, EPM_target_attachment, &attachments_num, &attachments);
	//获取参数
	char *url = NULL, *name = NULL, *password = NULL;
	char *argflag = NULL, *argvalue = NULL, *arg = NULL;
	int arg_cnt = TC_number_of_arguments(msg.arguments);
	char* uid;
	char *endResult;
	printf("参数个数为：%d\n", arg_cnt);
	*logFile << "参数个数为" << std::endl;
	if (arg_cnt > 0)
	{

		for (int i = 0; i<arg_cnt; i++)
		{
			//获取下一个参数（从0开始）
			arg = TC_next_argument(msg.arguments);
			//获取参数的名称和值
			ifail = ITK_ask_argument_named_value((const char*)arg, &argflag, &argvalue);
			if (stricmp(argflag, "LIMS") == 0)
			{
				if (argvalue != NULL)
				{
					url = argvalue;
					printf("获取的值%s\n", url);
					*logFile << "获取的值1" << std::endl;
				}
			}
			else if (stricmp(argflag, "NAME") == 0)
			{
				if (argvalue != NULL)
				{
					name = argvalue;
					printf("获取的值%s\n", name);
					*logFile << "获取的值2" << std::endl;
				}
			}
			else if (stricmp(argflag, "PASSWORD") == 0)
			{
				if (argvalue != NULL)
				{
					password = argvalue;
					printf("获取的值%s\n", password);
					*logFile << "获取的值3" << std::endl;
				}
			}
		}
		//调整 获取流程uid，保证数据的唯一性

		ITK__convert_tag_to_uid(rootTask, &uid);
		
		//调整，一次性发送多条数据
		//弹窗提示
		const char* error = "";
		string mees = "";
		for (int r = 0; r < attachments_num;r++) {
			//记录传递对象
			char* itemObjId;
			AOM_ask_value_string(attachments[r], "item_id", &itemObjId);
			*logFile << "************************************开始执行对象" << itemObjId << "************************************" << std::endl;
			//获取首选项
			std::map<std::string, std::string> valueMap;//统计集合
			//orderList
			std::map<std::string, std::string> orderValue;
			std::map<std::string, std::map<std::string, std::string>> orderMap;
			//根据首选项获取属性
			*logFile << "根据首选项RB_PLM2LIMS_JCSY获取属性" << std::endl;
			printf("根据首选项RB_PLM2LIMS_JCSY获取属性\n");
			int pref_cnt = 0;
			char** pref_vals = NULL;
			//获取首选项的值
			PREF_ask_char_values("RB_PLM2LIMS_JCSY", &pref_cnt, &pref_vals);
			if (pref_cnt > 0) {
				for (int i = 0; i < pref_cnt; i++) {
					char* getValue = "";
					char* val = pref_vals[i];
					*logFile << "开始分割字符串" << std::endl;
					*logFile << val << std::endl;
					printf("开始分割首选项%s\n", val);
					printf("开始分割字符串\n");
					vector<string> ans;
					Split(val, "-", ans);
					if (ans.size() > 0) {
						for (int j = 0; j < ans.size(); j++) {
							if (stricmp("true", (char*)ans[2].c_str()) == 0) {	//是lov属性	
								*logFile << "是lov属性" << std::endl;
								//Log::info("是lov属性");
								if (stricmp("true", (char*)ans[3].c_str()) == 0) {	//传递真实值
									*logFile << "传递真实值" << std::endl;
									//Log::info("传递真实值");
									if (stricmp("true", (char*)ans[4].c_str()) == 0) {	//封装进orderList
										*logFile << "封装进orderList" << std::endl;
										//Log::info("封装进orderList");
										int call;
										if (stricmp(ans[5].c_str(), "string") == 0) {
											*logFile << "获取到了字符串" << std::endl;
											ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue));
										}
										else if (stricmp(ans[5].c_str(), "date") == 0) {
											*logFile << "获取到了日期" << std::endl;
											date_t getdate;
											ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate));
											sprintf(getValue, "%d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day);
										}
										else if (stricmp(ans[5].c_str(), "array") == 0) {
											*logFile << "获取到了数组" << std::endl;
											int num; char** getValues;
											ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues));
											getValue = concat(getValues, num);
										}
										else {
											getValue = "***";
										}
										orderValue[ans[0].c_str()] = getValue;
									}
									else {	//不封装进orderList
										//Log::info("不封装进orderList");
										*logFile << "不封装进orderList" << std::endl;
										int call;
										if (stricmp(ans[5].c_str(), "string") == 0) {
											*logFile << "获取到了字符串" << std::endl;
											ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue));
										}
										else if (stricmp(ans[5].c_str(), "date") == 0) {
											*logFile << "获取到了日期" << std::endl;
											date_t getdate;
											ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate));
											sprintf(getValue, "%d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day);
										}
										else if (stricmp(ans[5].c_str(), "array") == 0) {
											*logFile << "获取到了数组" << std::endl;
											int num; char** getValues;
											ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues));
											getValue = concat(getValues, num);
										}
										else {
											getValue = "***";
										}
										valueMap[ans[0].c_str()] = getValue;
									}
								}
								else {	//传递显示值	
									*logFile << "传递显示值" << std::endl;
									//Log::info("传递显示值");
									if (stricmp("true", (char*)ans[4].c_str()) == 0) {	//封装进orderList
										*logFile << "封装进orderList" << std::endl;
										//Log::info("封装进orderList");
										int call;
										if (stricmp(ans[5].c_str(), "string") == 0) {
											*logFile << "获取到了字符串" << std::endl;
											ITKCALL(call = AOM_UIF_ask_value(attachments[r], ans[1].c_str(), &getValue));
										}
										else if (stricmp(ans[5].c_str(), "array") == 0) {
											*logFile << "获取到了数组" << std::endl;
											int num; char** getValues;
											ITKCALL(call = AOM_UIF_ask_values(attachments[r], ans[1].c_str(), &num, &getValues));
											getValue = concat(getValues, num);
										}
										else {
											getValue = "***";
										}
										orderValue[ans[0].c_str()] = getValue;
									}
									else {	//不封装进orderList
										*logFile << "不封装进orderList" << std::endl;
										//Log::info("不封装进orderList");
										int call;
										if (stricmp(ans[5].c_str(), "string") == 0) {
											*logFile << "获取到了字符串" << std::endl;
											ITKCALL(call = AOM_UIF_ask_value(attachments[r], ans[1].c_str(), &getValue));
										}
										else if (stricmp(ans[5].c_str(), "array") == 0) {
											*logFile << "获取到了数组" << std::endl;
											int num; char** getValues;
											ITKCALL(call = AOM_UIF_ask_values(attachments[r], ans[1].c_str(), &num, &getValues));
											getValue = concat(getValues, num);
										}
										else {
											getValue = "***";
										}
										valueMap[ans[0].c_str()] = getValue;
									}
								}
							}
							else {	//不是lov属性
								*logFile << "不是lov属性" << std::endl;
								//Log::info("不是lov属性");
								if (stricmp("true", (char*)ans[4].c_str()) == 0) {	//封装进orderList
									*logFile << "封装进orderList" << std::endl;
									//Log::info("封装进orderList");
									int call;
									if (stricmp(ans[5].c_str(), "string") == 0) {
										*logFile << "获取到了字符串" << std::endl;
										ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue));
									}
									else if (stricmp(ans[5].c_str(), "date") == 0) {
										*logFile << "获取到了日期" << std::endl;
										date_t getdate;
										*logFile << "开始赋值" << std::endl;
										ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate));
										*logFile << "赋值结束" << std::endl;
										printf("getdate %d", getdate);
										char fileDate[128] = "";
										sprintf_s(fileDate, "%04d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day);
										*logFile << "赋值成功" << std::endl;
										*logFile << fileDate << std::endl;
										getValue = fileDate;
									}
									else if (stricmp(ans[5].c_str(), "array") == 0) {
										*logFile << "获取到了数组" << std::endl;
										int num; char** getValues;
										ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues));
										getValue = concat(getValues, num);
									}
									else {
										getValue = "***";
									}
									orderValue[ans[0].c_str()] = getValue;
								}
								else {	//不封装进orderList
									//Log::info("不封装进orderList");
									*logFile << "不封装进orderList" << std::endl;
									int call;
									if (stricmp(ans[5].c_str(), "string") == 0) {
										*logFile << "获取到了字符串" << std::endl;
										ITKCALL(call = AOM_ask_value_string(attachments[r], ans[1].c_str(), &getValue));
									}
									else if (stricmp(ans[5].c_str(), "date") == 0) {
										*logFile << "获取到了日期" << std::endl;
										date_t getdate;
										*logFile << "开始赋值" << std::endl;
										ITKCALL(call = AOM_ask_value_date(attachments[r], ans[1].c_str(), &getdate));
										*logFile << "赋值结束" << std::endl;
										printf("getdate %d", &getdate);

										char fileDate[128] = "";
										sprintf_s(fileDate, "%04d-%02d-%02d 00:00", getdate.year, getdate.month + 1, getdate.day);
										*logFile << "赋值成功" << std::endl;
										*logFile << fileDate << std::endl;
										getValue = fileDate;
									}
									else if (stricmp(ans[5].c_str(), "array") == 0) {
										*logFile << "获取到了数组" << std::endl;
										int num; char** getValues;
										ITKCALL(call = AOM_ask_value_strings(attachments[r], ans[1].c_str(), &num, &getValues));
										getValue = concat(getValues, num);
									}
									else {
										getValue = "***";
									}
									valueMap[ans[0].c_str()] = getValue;
								}
							}
						}
					}
				}
				//将orderList整合
				*logFile << "将orderList整合" << std::endl;
				//Log::info("将orderList整合");
				orderMap["orderList"] = orderValue;
				//整合json
				std::string jsonStr = "[{";
				// 添加valueMap的值到JSON字符串
				for (auto it = valueMap.begin(); it != valueMap.end(); it++) {
					jsonStr += "\"" + it->first + "\":\"" + it->second + "\",";
				}
				// 添加orderMap的值到JSON字符串
				for (auto it = orderMap.begin(); it != orderMap.end(); it++) {
					std::map<std::string, std::string> order = it->second;
					jsonStr += "\"" + it->first + "\":[{";
					for (auto it2 = order.begin(); it2 != order.end(); it2++) {
						jsonStr += "\"" + it2->first + "\":\"" + it2->second + "\",";
					}
					if (order.size() > 0) {
						jsonStr.erase(jsonStr.end() - 1);
					}
					jsonStr += "},";
				}
				if (orderMap.size() > 0) {
					jsonStr.erase(jsonStr.end() - 1);
				}
				jsonStr += "]}]";
				// 输出JSON字符串
				std::cout << jsonStr << std::endl;


				//将json存储至本地
				char jsonFile[1024] = "";
				strcat(jsonFile, "D:\\TCTOLIMS\\");
				strcat(jsonFile, uid);
				strcat(jsonFile, "output.json");
				FILE* jsFile = fopen(jsonFile, "a+");

				if (jsFile == NULL) {
					// 文件不存在或者无法打开，尝试创建
					*logFile << "文件不存在或者无法打开，开始创建" << std::endl;
					if (errno != EEXIST) {
						return EXIT_FAILURE;
					}

					jsFile = fopen(jsonFile, "w");
					if (jsFile == NULL) {
						return EXIT_FAILURE;
					}
					*logFile << "文件创建成功，开始写入信息" << std::endl;
				}
				else {
					*logFile << "文件已存在，开始写入信息" << std::endl;
					fclose(jsFile);
				}

				std::ofstream ofs(jsonFile);
				ofs << jsonStr;
				ofs.close();
				*logFile << "保存成功" << std::endl;
				//使用java发送请求给接口
				printf("开始执行cmd方法");
				*logFile << "开始执行cmd方法" << std::endl;
				char cmd[1024] = "";
				strcpy(cmd, "java -jar D:\\Siemens\\Teamcenter12\\bin\\PostMain.jar");
				strcat(cmd, " ");
				strcat(cmd, url);
				strcat(cmd, " ");
				strcat(cmd, uid);
				*logFile << cmd << std::endl;
				printf("\n%s\n", cmd);
				system(cmd);
				*logFile << "cmd执行完毕" << std::endl;
				//读取本地的result文件
				string prefix = "D:\\TCTOLIMS\\";
				string suffix = "result.txt";
				string namepath = prefix +uid+ suffix;
				*logFile << "读取LIMS返回文件:" << namepath <<  std::endl;
				std::ifstream file1(namepath);
				if (!file1.is_open()) {
					std::cerr << "Failed to open file!" << std::endl;
					char* error = "服务未响应";
					EMH_store_error_s2(EMH_severity_error, ITK_err, "提示", error);
					return 1;
				}
				std::stringstream buffer1;
				buffer1 << file1.rdbuf();
				std::string resultStr = buffer1.str();
				*logFile << resultStr << std::endl;
				if (resultStr.find("false") != std::string::npos) {
					//写入属性值
					AOM_lock(attachments[r]);
					AOM_set_value_string(attachments[r], "rb3_limsInfo", resultStr.c_str());
					AOM_save(attachments[r]);
					AOM_unlock(attachments[r]);
					mees = mees + resultStr+"\n";
					
				}
				else {
					//写入属性值
					AOM_lock(attachments[r]);
					AOM_set_value_string(attachments[r], "rb3_limsInfo", resultStr.c_str());
					AOM_save(attachments[r]);
					AOM_unlock(attachments[r]);
					
				}
			}
		}
		POM_AM__set_application_bypass(false); // 关旁路
		if (strcmp("",mees.c_str())!=0) {
			EMH_store_error_s2(EMH_severity_error, ITK_err, "提示", mees.c_str());
			return 1;
		}
		else {
			return ITK_ok;
		}
		
			
	}
	return 0;
}