#include "selfcare_proxy.h"
#include "utils_queue.h"
#include "selfcare_udp.h"
#include "selfcare_endecode.h"
#include "selfcare_res.h"
#include "log.h"

extern int get_proxy_run_mode();
extern int rest_query_recharge_card_proc( struct rest_msg_s  *rest_ptr);
extern int rest_query_tariff_proc(struct rest_msg_s  *rest_ptr);
extern int rest_update_plan_info_proc(struct rest_msg_s  *rest_ptr);
extern int rest_update_ocs_del_result(struct rest_msg_s  *rest_ptr);
extern int rest_rent_charge_behalf_on_ocs(struct rest_msg_s  *rest_ptr);
extern int rest_update_subs_info_proc(struct rest_msg_s  *rest_ptr);
static int _httpserv_handle_udpresp(char *buff, int len)
{
	/* 解码ocs发送来回复的udp消息 */
    int ret;
	_rest_msg_s msg;
	memset(&msg, 0x00, sizeof(msg));
    ret = decode_rest_api_msg((u8*)buff, len, &msg);
	if(ret != 1)
	{
		LOG_E("[udp-handle] decode ocs resp err.ret[%d]\n", ret);
		return ret;
	}

	if(get_proxy_run_mode() == 4)//OCS+CRM mode
	{
		if(msg.msg_type == REST_UPDATE_RECHARGE_CARD_REQ)
		{
			LOG_E("[udp-handle] proc ocs REST_UPDATE_RECHARGE_CARD_REQ\n");

			rest_query_recharge_card_proc(&msg);
			
			return ret;
		}

		if(msg.msg_type == REST_CRM_QUERY_TARIFF_REQ)
		{
	//		LOG_E("[udp-handle] proc ocs REST_CRM_QUERY_TARIFF_REQ\n");

			rest_query_tariff_proc(&msg);
			
			return ret;
		}

		if(msg.msg_type == REST_CRM_UPDATE_PLAN_INFO_REQ)
		{
		//	LOG_E("[udp-handle] proc ocs REST_CRM_UPDATE_PLAN_INFO_REQ\n");

			rest_update_plan_info_proc( &msg);

			return ret;
		}

		if(msg.msg_type == REST_CRM_DELETE_SUBS_RES)
		{
		//	LOG_E("[udp-handle] proc ocs REST_CRM_DELETE_SUBS_RES\n");

			rest_update_ocs_del_result( &msg);

			return ret;
		}
		if(msg.msg_type == REST_CRM_RENT_CHARGE)
		{
		//	LOG_E("[udp-handle] proc ocs REST_CRM_RENT_CHARGE\n");

			rest_rent_charge_behalf_on_ocs( &msg);

			return ret;
		}

	
		if(msg.msg_type == REST_CRM_UPDATE_SUBS_REQ)
		{
		//	LOG_E("[udp-handle] proc ocs REST_CRM_UPDATE_SUBS_INFO_REQ\n");

			rest_update_subs_info_proc( &msg);

			return ret;
		}


		
	}
	
	int res_id = msg.header.dst_ref;
	if(res_id >= SELFCARE_RES_NUM)
	{
		LOG_E("[udp-handle] proc ocs resp err. res_id[%d], msg_type=%d\n", res_id, msg.msg_type);
		return FAILURE;
	}

	if(g_res_arr[res_id].state != SELFCARE_WAIT_OCS_RESP)
	{
		LOG_E("[udp-handle] recv udp err.res_id[%d] state[%s] expect[%s] \n",
                        res_id,
                        selfcare_res_stateprint(g_res_arr[res_id].state),
                        selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP) );
		return SUCCESS;
	}

	_rest_msg_s *resp = &g_res_arr[res_id].resp;
	memcpy(resp, &msg, sizeof(msg));
	if(g_res_arr[res_id].local_init_flag ==  1)
		g_res_arr[res_id].state = SELFCARE_LOCAL_INIT_RESP;
	else
		g_res_arr[res_id].state = SELFCARE_WAIT_SEND2SELFCARE_RESP;

	LOG_D("[udp-handle] recv udp suc.res_id[%d] state[%s=>%s]\n",
                res_id,
                selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP),
                selfcare_res_stateprint(g_res_arr[res_id].state) );
    
	return SUCCESS;
}

static int _httpserv_handle_httpreq(struct evhttp_request *req, void *arg, SELFCARE_URL_E req_type)
{
	int ret;

    ret = selfcare_httpsrv_check(req, arg);
    if(ret != SUCCESS)
    {
    	LOG_E("[httpserv] check failed\n");
        return ret;
    }

    int res_id;
    ret = selfcare_res_get(&res_id);
    if(ret != SUCCESS)
    {
        LOG_D("[httpserv] no res.\n");
        // send http-resp failed
        return ret;
    }

    selfcare_res_s *res = &g_res_arr[res_id];
	memset(res, 0x00, sizeof(selfcare_res_s));
	res->id = res_id;
   	 res->state = SELFCARE_WAIT_SEND2OCS_REQ;
	res->req = req;
	res->arg = arg;
	res->req_type = req_type;

	LOG_D("[httpserv] res_id[%d] get suc. state[%s] for type[%d]\n", res->id, selfcare_res_stateprint(res->state), req_type);
    
	return SUCCESS;
}

selfcare_res_s *selfcare_assign_res()
{
	int res_id, ret;
	selfcare_res_s *res=NULL;
	
	ret = selfcare_res_get(&res_id);
	
	if(ret != SUCCESS)
	{
		LOG_D("[httpserv] no res.\n");
		return NULL;
	}

	res = &g_res_arr[res_id];
	memset(res, 0x00, sizeof(selfcare_res_s));
	res->id = res_id;

	LOG_D("[httpserv] res_id[%d] get suc. state[%s]\n", res->id, selfcare_res_stateprint(res->state));
    
	return res;
}

static void _httpserv_handle_authcode(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_AUTHCODE);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle authcode err.\n");
		return ;
	}

	LOG_D("[httpserv] handle authcode suc.req[%p]\n", req);
	return ;
}

static void _httpserv_handle_queryuserdata(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_QUERY_USERDATA);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle queryuserdata err.\n");
		return ;
	}

	LOG_D("[httpserv] handle queryuserdata suc.\n");
	return ;
}
static void _httpserv_handle_bundlesubs(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_BUNDLE_SUBS);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle bundlesubs err.\n");
		return ;
	}

	LOG_D("[httpserv] handle bundlesubs suc.\n");
	return ;
}
static void _httpserv_handle_bundleusage(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_BUNDLE_USAGE);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle bundleusage err.\n");
		return;
	}

	LOG_D("[httpserv] handle bundleusage suc.\n");
	return ;
}
static void _httpserv_handle_recharge(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_RECHARGE);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle recharge err.\n");
		return ;
	}

	LOG_D("[httpserv] handle recharge suc.\n");
	return ;
}
static void _httpserv_handle_transfer(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_TRANSFER);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle transfer err.\n");
		return ;
	}

	LOG_D("[httpserv] handle transfer suc.\n");
	return ;
}

static void _httpserv_handle_rechargecard(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_RECHARGE_CARD	);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle rechargecard err.\n");
		return ;
	}

	LOG_D("[httpserv] handle rechargecard suc.\n");
	return ;
}
static void _httpserv_handle_checkbalance(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_CHECK_BALANCE	);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle checkbalance err.\n");
		return ;
	}

	LOG_D("[httpserv] handle checkbalance suc.\n");
	return ;
}

static void _httpserv_handle_querybalane(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_QUERY_BALANCE	);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle querybalane err.\n");
		return ;
	}

	LOG_D("[httpserv] handle querybalane suc.\n");
	return ;
}

static void _httpserv_handle_payment(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_CRM_PAYMENT	);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle crm payment err.\n");
		return ;
	}

	LOG_D("[httpserv] handle crm payment suc.\n");
	return ;
}

static void _httpserv_handle_smsdeliver(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_SMS_DELIVER);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle sms_deliver err.\n");
		return ;
	}

	LOG_D("[httpserv] handle sms_deliver suc.\n");
	return ;
}

static void _httpserv_handle_createaccount(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_CREATE_ACCT);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] handle create_account err.\n");
		return ;
	}

	LOG_D("[httpserv] handle create_account suc.\n");
	return ;
}

static void _httpserv_handle_updatesubs(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_UPDATE_SUBS);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] _httpserv_handle_updatesubs err.\n");
		return ;
	}

	LOG_D("[httpserv] _httpserv_handle_updatesubs suc.\n");
	return ;
}

static void _httpserv_handle_deletesubs(struct evhttp_request *req, void *arg)
{
	int ret;
	ret = _httpserv_handle_httpreq(req, arg, SELFCARE_DELETE_SUBS);
	if(ret != SUCCESS)
	{
		LOG_E("[httpserv] _httpserv_handle_updatesubs err.\n");
		return ;
	}

	LOG_D("[httpserv] _httpserv_handle_updatesubs suc.\n");
	return ;
}

static int _selfcare_proxy_reg(const SELFCARE_URL_E url_type,
							   const char *url_addr,
							   void (*handle)(struct evhttp_request *req, void *arg) )
{
	selfcare_elem_s elem;
	memset(&elem, 0x00, sizeof(elem));

	elem.url_type = url_type;
	strncpy(elem.url_addr, url_addr, SELFCARE_URL_LEN);
	elem.handle = handle;

	return selfcare_httpsrv_reg(&elem);
}


int selfcare_proxy_init(int argc, char **argv)
{
    int ret;
    /* 初始化配置 */
    ret = selfcare_config_init(NULL);
    if(ret != SUCCESS)
    {
        return ret;
    }
    
    /* 初始化udp socket */
    ret = selfcare_udp_init();
    if(ret != SUCCESS)
    {
        return ret;
    }    

	/* 注册selfcare请求回调函数 */
	ret = _selfcare_proxy_reg(SELFCARE_AUTHCODE, 		selfcare_config_get()->authcode_url, 		_httpserv_handle_authcode);
	ret += _selfcare_proxy_reg(SELFCARE_QUERY_USERDATA,  selfcare_config_get()->query_userdata_url, 	_httpserv_handle_queryuserdata);
	ret += _selfcare_proxy_reg(SELFCARE_BUNDLE_SUBS, 		selfcare_config_get()->bundle_subs_url, 	_httpserv_handle_bundlesubs);
	ret += _selfcare_proxy_reg(SELFCARE_BUNDLE_USAGE, 	selfcare_config_get()->bundle_usage_url, 	_httpserv_handle_bundleusage);
	ret += _selfcare_proxy_reg(SELFCARE_RECHARGE, 		selfcare_config_get()->recharge_url, 		_httpserv_handle_recharge);
	ret += _selfcare_proxy_reg(SELFCARE_TRANSFER, 		selfcare_config_get()->transfer_url, 		_httpserv_handle_transfer);
	ret += _selfcare_proxy_reg(SELFCARE_RECHARGE_CARD, 	selfcare_config_get()->recharge_card_url, 	_httpserv_handle_rechargecard);
	ret += _selfcare_proxy_reg(SELFCARE_CHECK_BALANCE, 	selfcare_config_get()->check_balance_url, 	_httpserv_handle_checkbalance);
	ret += _selfcare_proxy_reg(SELFCARE_QUERY_BALANCE, 	selfcare_config_get()->query_balane_url, 	_httpserv_handle_querybalane);
	ret += _selfcare_proxy_reg(SELFCARE_CRM_PAYMENT, 	selfcare_config_get()->payment_url	, 		_httpserv_handle_payment);
	ret += _selfcare_proxy_reg(SELFCARE_SMS_DELIVER, 		selfcare_config_get()->sms_deliver_url, 		_httpserv_handle_smsdeliver);
	ret += _selfcare_proxy_reg(SELFCARE_CREATE_ACCT, 	selfcare_config_get()->create_account_url, 	_httpserv_handle_createaccount);
	ret += _selfcare_proxy_reg(SELFCARE_UPDATE_SUBS, 	selfcare_config_get()->update_subs_url, 	_httpserv_handle_updatesubs);
	ret += _selfcare_proxy_reg(SELFCARE_DELETE_SUBS, 		selfcare_config_get()->delete_subs_url, 		_httpserv_handle_deletesubs);
	
	/* 注册ocs udp消息回调函数 */
	selfcare_udp_handle_s handle;
	handle.handle = _httpserv_handle_udpresp;
	ret = selfcare_udp_reg(&handle);
    if(ret != SUCCESS)
    {
        return ret;
    }

	ret = selfcare_res_init(argc, argv);
	if(ret != SUCCESS)
    {
        return ret;
    }
	
	ret = selfcare_httpsrv_init(argc, argv);
    if(ret != SUCCESS)
    {
        return ret;
    }
	
	return SUCCESS;
}

void selfcare_proxy_uninit(void)
{
    selfcare_config_uninit();
    selfcare_udp_uninit();
    selfcare_httpsrv_uninit();
    
	selfcare_res_uninit();
}

