#include "handlers.h"
#include "string_utils.h"
#include <tccore\aom.h>
#include <tccore\aom_prop.h>
#include <user_exits/epm_toolkit_utils.h>
#include <tccore/item.h>

string prop(tag_t comp, const char *prop) {
	char **value = NULL;
	int vcnt = 0;
	string val;
	if (strcmp(prop, "status") == 0) {
		ITKCALL(AOM_ask_displayable_values(comp, "release_status_list", &vcnt, &value));
	}
	else {
		ITKCALL(AOM_ask_displayable_values(comp, prop, &vcnt, &value));
	}
	if (vcnt == 0) {
		val = "";
	}
	else if (vcnt == 1) {
		val = value[0];
	}
	else if (strcmp(prop, "status") == 0) {
		val = value[vcnt - 1];
	}
	else {
		for (int i = 0; i < vcnt; i++) {
			if (i > 0) {
				val.append("&");
			}
			val.append(value[i]);
		}
	}
	printf("prop: %s = [%s]\n", prop, val.c_str());
	return val;
}

int JD_Check_StatusAndProp(EPM_rule_message_t msg){
	printf("*******************************************************************************\n");
	printf("*                     JD_Check_StatusAndProp is comming ！                    *\n");
	printf("*******************************************************************************\n");
	tag_t task = NULLTAG, job = NULLTAG, *attachments = NULL;
	int ifail = ITK_ok, cnt = 0, tcnt = 0, pcnt = 0, rcnt = 0, ccnt = 0;
	char **types = NULL, **props = NULL, **rels = NULL, *childs = NULL;
	string mes = "";

	cnt = TC_number_of_arguments(msg.arguments);
	TC_init_argument_list(msg.arguments);
	for (int ix = 0; ix < cnt; ix++)
	{
		char *trans_args_value = TC_next_argument(msg.arguments);
		char *para_flag = NULL, *para_value = NULL;

		ITKCALL(ITK_ask_argument_named_value(trans_args_value, &para_flag, &para_value));

		if (tc_strcmp(para_flag, "type") == 0)
		{
			ITKCALL(EPM__parse_string(para_value, ",", &tcnt, &types));
			//tc_strcpy(approver_attr, para_value);
		}
		else if (tc_strcmp(para_flag, "prop") == 0)
		{
			ITKCALL(EPM__parse_string(para_value, ";", &pcnt, &props));
			//approvedate_attr = (char*)MEM_alloc((strlen(para_value) + 1) * sizeof(char*));
			//tc_strcpy(approvedate_attr, para_value);
		}
		else if (tc_strcmp(para_flag, "relation") == 0)
		{
			ITKCALL(EPM__parse_string(para_value, ";", &rcnt, &rels));
		}
		else if (tc_strcmp(para_flag, "child") == 0)
		{
			//ITKCALL(EPM__parse_string(para_value, ";", &pcnt, &props));
			childs = (char*)MEM_alloc((strlen(para_value) + 1) * sizeof(char*));
			tc_strcpy(childs, para_value);
			ccnt = 1;
		}
		else if (tc_strcmp(para_flag, "message") == 0)
		{
			mes = para_value;
		}

		if (para_flag) { MEM_free(para_flag); para_flag = NULL; }
		if (para_value) { MEM_free(para_value); para_value = NULL; }
	}

	//task = msg.task;
	cnt = 0;
	ITKCALL(EPM_ask_job(msg.task, &job));
	ITKCALL(EPM_ask_root_task(job, &task));
	ITKCALL(ifail = EPM_ask_attachments(task, EPM_target_attachment, &cnt, &attachments));
	printf("attachments:%d\n", cnt);
	string message = "";
	for (int t = 0; t < cnt; t++) {
		char *type = NULL;
		bool check = true;
		ITKCALL(WSOM_ask_object_type2(attachments[t], &type));
		printf("type:%s\n", type);
		for (int i = 0; i < tcnt; i++) {
			if (strcmp(types[i], type) == 0) {
				check = false;
				break;
			}
		}
		if (check)
			continue;
		tag_t item = NULLTAG;
		ITKCALL(ITEM_ask_item_of_rev(attachments[t], &item));
		check = true;
		for (int p = 0; p < pcnt; p++) {
			vector<string> andv;
			Split(props[p], ",", andv);
			bool next = false;
			for (int a = 0; a < andv.size(); a++) {
				vector<string> propv, pv;
				//char *value = NULL;
				string val;
				//if (andv[a].find("\^") > 0) {
				if (contains(andv[a].c_str(), '^') > 0) {
					Split(andv[a], "^", propv);
					Split(propv[0], ".", pv);
					/*if (strcmp(pv[0].c_str(), "item") == 0) {
						ITKCALL(AOM_ask_value_string(item, pv[1].c_str(), &value));
					}
					else if (strcmp(pv[0].c_str(), "rev") == 0) {
						ITKCALL(AOM_ask_value_string(attachments[t], pv[1].c_str(), &value));
					}*/
					if (strcmp(pv[0].c_str(), "item") == 0) {
						val = prop(item, pv[1].c_str());
					}
					else if (strcmp(pv[0].c_str(), "rev") == 0) {
						val = prop(attachments[t], pv[1].c_str());
					}
					if (val.find(propv[1]) == andv[a].npos) {
						next = true;
						break;
					}
				}
				else if (andv[a].find("!=") != andv[a].npos) {
					Split(andv[a], "!=", propv);
					Split(propv[0], ".", pv);
					if (strcmp(pv[0].c_str(), "item") == 0) {
						val = prop(item, pv[1].c_str());
					}
					else if (strcmp(pv[0].c_str(), "rev") == 0) {
						val = prop(attachments[t], pv[1].c_str());
					}
					if (strcmp(propv[1].c_str(), "NULL") == 0) {
						printf("size: %zd\n", val.size());
						if (val.size() == 0) {
							next = true;
							break;
						}
					}
					else if (strcmp(propv[1].c_str(), val.c_str()) == 0) {
						next = true;
						break;
					}
				}
				else if (andv[a].find("=") != andv[a].npos) {
					Split(andv[a], "=", propv);
					Split(propv[0], ".", pv);
					if (strcmp(pv[0].c_str(), "item") == 0) {
						val = prop(item, pv[1].c_str());
					}
					else if (strcmp(pv[0].c_str(), "rev") == 0) {
						val = prop(attachments[t], pv[1].c_str());
					}
					if (strcmp(propv[1].c_str(), "NULL") == 0) {
						printf("size: %zd\n", val.size());
						if (val.size() != 0) {
							next = true;
							break;
						}
					}
					else if (strcmp(propv[1].c_str(), val.c_str()) != 0) {
						next = true;
						break;
					}
				}
			}
			if (next) {
				continue;
			}
			check = false;
			break;
		}
		if (check) {
			if (rcnt == 0 && ccnt == 0) {
				char *os = NULL;
				ITKCALL(AOM_ask_value_string(attachments[t], "object_string", &os));
				if (mes.size() == 0) {
					message = "0";
					continue;
				}
				string m = replace(mes, "%s", os);
				m = replace(m, "%d", "参数2");
				message.append(m).append("\n");
			}
			continue;
		}
		//参数3
		check = true;
		for (int i = 0; i < rcnt; i++) {
			vector<string> andv;
			Split(rels[i], ",", andv);
			bool next = false;
			for (int a = 0; a < andv.size(); a++) {
				vector<string> propv;
				int rc = 0;
				tag_t *value = NULL;
				if (andv[a].find("!=") != andv[a].npos) {
					Split(andv[a], "!=", propv);
					ITKCALL(AOM_ask_value_tags(attachments[t], propv[0].c_str(), &rc, &value));
					if (rc == 0) {
						next = true;
						break;
					}
				}
				else if (andv[a].find("=") != andv[a].npos) {
					Split(andv[a], "=", propv);
					ITKCALL(AOM_ask_value_tags(attachments[t], propv[0].c_str(), &rc, &value));
					if (rc > 0) {
						next = true;
						break;
					}
				}
			}
			if (next)
				continue;
			check = false;
			break;
		}
		if (rcnt > 0 && check) {
			char *os = NULL;
			ITKCALL(AOM_ask_value_string(attachments[t], "object_string", &os));
			if (mes.size() == 0) {
				message = "0";
				continue;
			}
			string m = replace(mes, "%s", os);
			m = replace(m, "%d", "参数3");
			message.append(m).append("\n");
			continue;
		}
		//参数4
		if (ccnt > 0) {
			vector<string> tpv, orv;
			tag_t *child = NULL;
			int rc = 0;
			Split(childs, "@", tpv);
			Split(tpv[2], ";", orv);
			ITKCALL(AOM_ask_value_tags(attachments[t], tpv[0].c_str(), &rc, &child));
			int c4 = 0;
			if (rc == 0) {
				char *os = NULL;
				ITKCALL(AOM_ask_value_string(attachments[t], "object_string", &os));
				if (mes.size() == 0) {
					message = "0";
					continue;
				}
				string m = replace(mes, "%s", os);
				m = replace(m, "%d", "参数4");
				message.append(m).append("\n");
				continue;
			}
			for (int i = 0; i < rc; i++) {
				char *ctp = NULL;
				ITKCALL(WSOM_ask_object_type2(child[i], &ctp));
				if (strcmp(tpv[1].c_str(), ctp) != 0) {
					continue;
				}
				bool checkc = true;
				tag_t citem = NULLTAG;
				ITKCALL(ITEM_ask_item_of_rev(child[i], &citem));
				for (int o = 0; o < orv.size(); o++) {
					vector<string> andv;
					Split(orv[o], ",", andv);
					bool next = false;
					for (int a = 0; a < andv.size(); a++) {
						vector<string> propv, pv;
						char **value = NULL;
						int vcnt = 0;
						string val;
						if (contains(andv[a].c_str(), '^') > 0) {
							Split(andv[a], "^", propv);
							Split(propv[0], ".", pv);
							if (strcmp(pv[0].c_str(), "item") == 0) {
								//ITKCALL(AOM_ask_value_string(citem, pv[1].c_str(), &value));
								val = prop(citem, pv[1].c_str());
							}
							else if (strcmp(pv[0].c_str(), "rev") == 0) {
								//ITKCALL(AOM_ask_value_string(child[i], pv[1].c_str(), &value));
								val = prop(child[i], pv[1].c_str());
							}
							if (val.find(propv[1]) == andv[a].npos) {
								next = true;
								break;
							}
						}
						else if (andv[a].find("!=") != andv[a].npos) {
							Split(andv[a], "!=", propv);
							Split(propv[0], ".", pv);
							if (strcmp(pv[0].c_str(), "item") == 0) {
								val = prop(citem, pv[1].c_str());
							}
							else if (strcmp(pv[0].c_str(), "rev") == 0) {
								val = prop(child[i], pv[1].c_str());
							}
							if (strcmp(propv[1].c_str(), "NULL") == 0) {
								printf("size: %zd\n", val.size());
								if (val.size() == 0) {
									next = true;
									break;
								}
							}
							else if (strcmp(propv[1].c_str(), val.c_str()) == 0) {
								next = true;
								break;
							}
						}
						else if (andv[a].find("=") != andv[a].npos) {
							Split(andv[a], "=", propv);
							Split(propv[0], ".", pv);
							if (strcmp(pv[0].c_str(), "item") == 0) {
								val = prop(citem, pv[1].c_str());
							}
							else if (strcmp(pv[0].c_str(), "rev") == 0) {
								val = prop(child[i], pv[1].c_str());
							}
							if (strcmp(propv[1].c_str(), "NULL") == 0) {
								printf("size: %zd\n", val.size());
								if (val.size() != 0) {
									next = true;
									break;
								}
							}
							else if (strcmp(propv[1].c_str(), val.c_str()) != 0) {
								next = true;
								break;
							}
						}
					}
					if (next)
						continue;
					checkc = false;
					if (c4 == 0)
						c4 = 2;
					break;
				}
				if (checkc) {
					c4 = 1;
					break;
				}
			}
			if (c4 < 2) {
				char *os = NULL;
				ITKCALL(AOM_ask_value_string(attachments[t], "object_string", &os));
				if (mes.size() == 0) {
					message = "0";
					continue;
				}
				string m = replace(mes, "%s", os);
				m = replace(m, "%d", "参数4");
				message.append(m).append("\n");
				continue;
			}
		}
	}
	printf("message:%s\n", message.c_str());
	if (message.size() > 0) {
		if (strcmp(message.c_str(), "0") == 0) {
			ITKCALL(EMH_store_error(EMH_severity_user_error, 919821));
			return EPM_nogo;
		}
		ITKCALL(EMH_store_error_s1(EMH_severity_user_error, 919821, message.c_str()));
		return EPM_nogo;
	}

	return EPM_go;
}