#include "comn.h"

int ConnectSocket(char path[20]);
void ParsingResult(char recv_buf[1000]);
void PrintExecuteResult();

int main(int argc, char *argv[]) {
	// check command argument
	if (argc != 4) {
		printf("### no enough arguments ###\n");
		return 0;
	}
	char file_path[20];
	memset(file_path, 0, sizeof(file_path));
	sprintf(file_path, "./json/%s.json", argv[3]);
	printf("file_path : %s\n", file_path);

	// check file exist
	if (-1 == access(file_path, 0)) {
		printf("### no exist file path ###\n");
		return 0;
	}
	// socket connection
	char msg_buf[1000] = {0, };
	char recv_buf[1000] = {0, };
	char path[20];
	int is_connect = 0;
	FILE *file;
	int i = 1;
	json_t *jstr;
	json_error_t *error;

	memset(path, 0, sizeof(path));
	sprintf(path, "tcp://%s:%s", argv[1], argv[2]);
	printf("path :: %s\n", path);

	is_connect = ConnectSocket(path);
	if(0 != is_connect) {
		printf("## socket connect fail ##\n");
		return;
	}
	printf("## socket connect success ##\n");

	// check json file open
	file = fopen(file_path, "r");
	if(NULL == file) {
		printf("## file open fail ##\n");
		return;
	}
	printf("## file open success ##\n");

	// load file
	while (!feof(file)) {
		if (fgets(msg_buf, sizeof(msg_buf), file) == 0) {
			strcpy(msg_buf, "exit");
			if (-1 == zmq_send(requester, msg_buf, sizeof(msg_buf), 0)) {
				printf("## send fail ##\n");
				break;
			}
			if (-1 == zmq_recv(requester, recv_buf, sizeof(recv_buf), 0)) {
				printf("## recv fail ##\n");
				break;
			}
			ParsingResult(recv_buf);
			break;
		}

		printf("msg_buf :: %s\n", msg_buf);
		// check json format
		jstr = json_loads(msg_buf, 0, &error);
		if(!json_is_object(jstr)) {
			printf("## not json format ##");
			break;
		}

		printf("msg send ···\n");

		if(i < MULTIPART_MAX) {
			if (-1 == zmq_send(requester, msg_buf, sizeof(msg_buf), ZMQ_SNDMORE)) {
				printf("## send fail ##\n");
				break;
			}
		} else {
			if (-1 == zmq_send(requester, msg_buf, sizeof(msg_buf), 0)) {
				printf("## send fail ##\n");
				break;
			}
			if (-1 == zmq_recv(requester, recv_buf, sizeof(recv_buf), 0)) {
				printf("## recv fail ##\n");
				break;
			}
			// recv_buf 파싱 처리하고 결과값 계속 누적
			ParsingResult(recv_buf);

			i = 0;
		}

		i++;
		sleep(1);
	}

	if(0 != fclose(file)) {
		printf("## file close fail ##\n");
	}
	printf("## file close success ##\n");
	PrintExecuteResult();

	return 0;
}

int ConnectSocket(char path[20]) {
	context = zmq_ctx_new();
	assert(context != NULL);
	requester = zmq_socket(context, ZMQ_REQ);
	assert(requester != NULL);

	// socket connect
	int result = 0;
	result = zmq_connect(requester, path);
	return result;
}

void ParsingResult(char recv_buf[1000]) {
	printf("\n### recv_buf ###\n%s\n", recv_buf);
	json_t *result_json;
	json_error_t *error;
	json_t *key, *obj;
	json_int_t result_value;

	result_json = json_loads(recv_buf, 0, &error);

	json_object_foreach(result_json, key, obj) {
		if(json_is_integer(obj)) {
			result_value = json_integer_value(obj);

			if(0 == strcmp(key, "total_count")) {
				total_count += result_value;
			} else if(0 == strcmp(key, "insert_count")) {
				insert_count += result_value;
			} else if(0 == strcmp(key, "insert_success")) {
				insert_success += result_value;
			}  else if(0 == strcmp(key, "update_count")) {
				update_count += result_value;
			}  else if(0 == strcmp(key, "update_success")) {
				update_success += result_value;
			}  else if(0 == strcmp(key, "delete_count")) {
				delete_count += result_value;
			}  else if(0 == strcmp(key, "delete_success")) {
				delete_success += result_value;
			} 
		}
	}
}

void PrintExecuteResult() {
	printf("[Result] DML Count : %d\n", total_count);
	printf("Insert : %d/%d\n", insert_success, insert_count);
	printf("Update : %d/%d\n", update_success, update_count);
	printf("Delete : %d/%d\n", delete_success, delete_count);
}
