#include "hiredis/hiredis.h"
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#ifndef CONFIG_H
#define CONFIG_H

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct configItem
{
	char key[20];
	char value[50];
};

void config(char *configFilePath, struct configItem * configVar, int configNum);

#endif

/*
 * 字符串中寻找以等号分开的键值对
 * @param  src	源字符串 [输入参数]
 * @param  key	   键    [输出参数]
 * @param value	   值    [输出参数]
 */
static int strkv(char *src, char *key, char *value)
{
	char *p,*q;
	p = strchr(src, '=');	// p找到等号
	q = strchr(src, '\n');	// q找到换行

	// 如果有等号有换行
	if (p != NULL && q != NULL)
	{
		*q = '\0'; // 将换行设置为字符串结尾
		strncpy(key, src, p - src); // 将等号前的内容拷贝到 key 中
		strcpy(value, p+1);	// 将等号后的内容拷贝到 value 中
		return 1;
	}else
	{
		return 0;
	}
}

void config(char *configFilePath, struct configItem * configVar, int configNum)
{
	int i;
	FILE *fd;
	char buf[50]="";	// 缓冲字符串
	char key[50]="";	// 配置变量名
	char value[50]="";	// 配置变量值	

	fd = fopen(configFilePath, "r");

	if (fd == NULL)
	{
		printf("配置文件打开失败!\n");
		system("pause");
		exit(-1);
	}

	// 依次读取文件的每一行
	while(fgets(buf, 50, fd))
	{
		// 读取键值对
		if (strkv(buf, key, value))
		{
			// 读取成功则循环与配置数组比较
			for(i = 0; i< configNum; i++)
			{
				// 名称相等则拷贝
				if (strcmp(key, configVar[i].key) == 0)
				{				
					strcpy(configVar[i].value, value);
				}				
			}
			// 清空 读取出来的 key
			memset(key, 0, strlen(key));
		}
	}

	fclose(fd);
}

int get_count;
int set_count;
double get_bits;

#define BUF_SIZE 1024*3
char buf[BUF_SIZE + 1];

int all_id;

char KEY[1001][5];

void *do_job2(void *arg)
{
	redisContext* ctx;
	redisReply *res2;
	int id;

	id = __sync_fetch_and_add(&all_id,1);
	int timeout = 500000;
	
	int i;
	ctx = redisConnect(arg, 22129);
	if (ctx->err) {
		printf("failed \n");
		return NULL;
	}
	printf("connected %d\n",id);
	fflush(stdout);

	char key[32];
	for(i = 0;i != 1000;++i)
	{
		sprintf(key,"%s%s",KEY[id],KEY[i]);
		res2 = redisCommand(ctx, "set %s %s", key ,buf,timeout);
		__sync_add_and_fetch(&set_count,1);
		//printf("%s id%s i%s\n",key,KEY[id],KEY[i]);
		//fflush(stdout);
		if(res2 == NULL){
			printf("failed set \n");
			break;
		}
		if(res2->type == REDIS_REPLY_ERROR){
			printf("failed set \n");
			freeReplyObject(res2);
			break;
		}
		freeReplyObject(res2);
	}
	redisFree(ctx);

	printf("finished %d,all %d\n",id,set_count);
	fflush(stdout);
	return NULL;
}

void *do_job(void *arg)
{
	redisContext* ctx;
	redisReply *res1;
	//redisReply *res2;

	int timeout = 500000;

	//printf("connecting %d \n",++connecting_count);
	ctx = redisConnect(arg, 22129);
	if (ctx->err) {
		//printf("failed %d\n",++failed_count);
		return 0;
	}

	char key[128];
	//printf("success %d\n",++success_count);
	while(1)
	{
		int i = rand()%1000000;
		sprintf(key,"%d",i);
		switch (strlen(key)){
			case 1:sprintf(key,"00000%d",i);break;
			case 2:sprintf(key,"0000%d",i);break;
			case 3:sprintf(key,"000%d",i);break;
			case 4:sprintf(key,"00%d",i);break;
			case 5:sprintf(key,"0%d",i);break;
			default :;
		}

		res1 = redisCommand(ctx, "get %s", key ,timeout);
		if(res1 == NULL){
			continue ;
		}
		if(res1->type != REDIS_REPLY_STRING){
			freeReplyObject(res1);
			continue ;
		}
		get_count++;
		get_bits += strlen(res1->str);
		
		freeReplyObject(res1);
	}
	redisFree(ctx);

	return NULL;
}

struct configItem g_config_list[] = {
		{"each_pool", ""},
		{"ip1", ""},
		{"ip2", ""},
		{"ip3", ""},
		{"ip4", ""},
		{"ip5", ""},
		{"ip6", ""},
		{"ip7", ""},
		{"ip8", ""}
};

int main()
{
	signal(SIGPIPE, SIG_IGN);
	//thread_init(200);
	srand(time(NULL));

	config("test.config", g_config_list, sizeof(g_config_list)/sizeof(struct configItem));
	memset(buf,'1',BUF_SIZE);

	int i,j;

	for(i = 0;i != 1000;++i){
		sprintf(KEY[i],"%d",i);
		switch (strlen(KEY[i])){
			case 1:sprintf(KEY[i],"00%d",i);break;
			case 2:sprintf(KEY[i],"0%d",i);break;
			default :;
		}
	}

	i = 0;
	j = 0;

	for(j = 0;j != 9;++j){
		if(g_config_list[j].value[0] == 'N')
			break;
	}

	int ip_counts = j - 1;
	int each_pool = strtol(g_config_list[0].value,0,10);
	printf("%d %d\n",ip_counts,each_pool);
	pthread_t *id = malloc(ip_counts * sizeof(pthread_t) * each_pool);
	for(j = 1;j != ip_counts + 1;++j){
		for(i = j * each_pool;i != (j + 1) * each_pool;++i)
			pthread_create(&id[i],NULL,do_job,g_config_list[j].value);
	}
	sleep(1000000000);
	return 0;
}

config_file:
each_pool=1000
ip1=172.16.200.69
ip2=172.16.200.70
ip3=N172.16.200.104
ip4=N172.16.200.106
ip5=N172.16.3.14
ip6=N172.16.3.15
ip7=N172.16.3.16
ip8=N172.16.3.17