package com.palmnest.application.core.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.palmnest.application.ElementConstant;
import com.palmnest.application.OAuthConstants;
import com.palmnest.dao.wechat.ReplayContentDao;
import com.palmnest.model.estateserve.AppUser;
import com.palmnest.service.wechat.WeChatApiManager;
import com.palmnest.webapp.controller.wechat.NeigouController;

public class NeigouOAuthUtils {

	private static Logger LOG = Logger.getLogger(NeigouOAuthUtils.class);

	public static NeigouOAuth2Details createOAuthDetails(Properties config) {

		NeigouOAuth2Details oauthDetails = new NeigouOAuth2Details();
		oauthDetails.setAccessToken((String) config.get(OAuthConstants.ACCESS_TOKEN));
		oauthDetails.setRefreshToken((String) config.get(OAuthConstants.REFRESH_TOKEN));
		oauthDetails.setGrantType((String) config.get(OAuthConstants.GRANT_TYPE));
		oauthDetails.setClientId((String) config.get(OAuthConstants.CLIENT_ID));
		oauthDetails.setClientSecret((String) config.get(OAuthConstants.CLIENT_SECRET));
		oauthDetails.setScope((String) config.get(OAuthConstants.SCOPE));
		oauthDetails.setAuthenticationServerUrl((String) config.get(OAuthConstants.AUTHENTICATION_SERVER_URL));
		oauthDetails.setUsername((String) config.get(OAuthConstants.USERNAME));
		oauthDetails.setPassword((String) config.get(OAuthConstants.PASSWORD));
		oauthDetails.setResourceServerUrl((String) config.get(OAuthConstants.RESOURCE_SERVER_URL));

		oauthDetails.setSurl((String) config.get(OAuthConstants.SURL));
		oauthDetails.setGateway_url((String) config.get(OAuthConstants.GATEWAY_URL));
		oauthDetails.setCreateuser_url((String) config.get(OAuthConstants.CREATEUSER_URL));
		oauthDetails.setCreatecompany_url((String) config.get(OAuthConstants.CREATECOMPANY_URL));
		oauthDetails.setDefault_companyid((String) config.get(OAuthConstants.DEFAULT_COMPANYID));
		oauthDetails.setCreatelogintoken_url((String) config.get(OAuthConstants.CREATELOGINTOKEN_URL));
		oauthDetails.setGetUserMessage_url((String) config.get(OAuthConstants.GETUSERMESSAGE_URL));

		if (!isValid(oauthDetails.getResourceServerUrl())) {
			LOG.info("Resource server url is null. Will assume request is for generating Access token");
			oauthDetails.setAccessTokenRequest(true);
		}

		return oauthDetails;
	}

	public static Properties getClientConfigProps(String path) {
		//InputStream is = NeigouOAuthUtils.class.getClassLoader().getResourceAsStream(path);

		InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path);

		Properties config = new Properties();
		try {
			config.load(is);
		} catch (IOException e) {
			LOG.info("Could not load properties from " + path);
			e.printStackTrace();
			return null;
		}
		return config;
	}

	/*public static void getProtectedResource(NeigouOAuth2Details oauthDetails) {
		String resourceURL = oauthDetails.getResourceServerUrl();
				
		HttpGet get = new HttpGet(resourceURL);
		get.addHeader(OAuthConstants.AUTHORIZATION,
				getAuthorizationHeaderForAccessToken(oauthDetails.getAccessToken()));
		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		int code = -1;
		try {
			response = client.execute(get);
			code = response.getStatusLine().getStatusCode();
			if (code == 401 || code == 403) {
				// Access token is invalid or expired.Regenerate the access
				// token
				System.out
						.println("Access token is invalid or expired. Regenerating access token....");
				String accessToken = getAccessToken(oauthDetails);
				if (isValid(accessToken)) {
					// update the access token
					// LOG.info("New access token: " + accessToken);
					oauthDetails.setAccessToken(accessToken);
					get.removeHeaders(OAuthConstants.AUTHORIZATION);
					get.addHeader(OAuthConstants.AUTHORIZATION,
							getAuthorizationHeaderForAccessToken(oauthDetails
									.getAccessToken()));
					get.releaseConnection();
					response = client.execute(get);
					code = response.getStatusLine().getStatusCode();
					if (code >= 400) {
						throw new RuntimeException(
								"Could not access protected resource. Server returned http code: "
										+ code);

					}

				} else {
					throw new RuntimeException(
							"Could not regenerate access token");
				}

			}

			handleResponse(response);

		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			get.releaseConnection();
		}

	}*/
	
    /*public static String getAccessToken(NeigouOAuth2Details oauthDetails) throws Exception{
		
		LOG.info("NeigouOAuthUtils--getAccessToken start ======");			
		
		String clientId = oauthDetails.getClientId();
		String clientSecret = oauthDetails.getClientSecret();

		String accessToken = "";
		
		//Map<String,Map> jsonMap=new HashMap<String,Map>();
		
		Map<String,String> map=new HashMap<String,String>();
		map.put(OAuthConstants.GRANT_TYPE, oauthDetails.getGrantType());
		map.put(OAuthConstants.CLIENT_ID, clientId);
		map.put(OAuthConstants.CLIENT_SECRET, clientSecret);
		//jsonMap.put("data", jsonMap);
		
		String jsonMapStr=JSONObject.toJSONString(map);
		String jsonSendMsg="data="+jsonMapStr;
		
		//LOG.info("getAccessToken"+DateUtils.getDate("yyyy-MM-dd HH:ss:mm")+" sendMsg:"+sendMsg);
		String result=HttpKit.post(oauthDetails.getAuthenticationServerUrl(), jsonSendMsg);
		
		map = handleResponseJson(result);
		
		LOG.info("NeigouOAuthUtils--getAccessToken map======"+map.toString());	
		
		JSONObject tokenJsonData=JSONObject.parseObject((String)map.get("Data"));
		if(tokenJsonData.containsKey("access_token")){
			accessToken=(String) tokenJsonData.get("access_token");
		}
		

		LOG.info("NeigouOAuthUtils--getAccessToken end ======");			
		return accessToken;
	}*/

	public static String getAccessToken(NeigouOAuth2Details oauthDetails) {

		LOG.info("NeigouOAuthUtils--getAccessToken start ======");

		HttpPost post = new HttpPost(oauthDetails.getAuthenticationServerUrl());
		String clientId = oauthDetails.getClientId();
		String clientSecret = oauthDetails.getClientSecret();
		String scope = oauthDetails.getScope();

		List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
		parametersBody.add(new BasicNameValuePair(OAuthConstants.GRANT_TYPE, oauthDetails.getGrantType()));

		parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_ID, clientId));

		parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_SECRET, clientSecret));

		if (isValid(scope)) {
			parametersBody.add(new BasicNameValuePair(OAuthConstants.SCOPE, scope));
		}

		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		String accessToken = null;
		try {
			post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));

			response = client.execute(post);
			int code = response.getStatusLine().getStatusCode();
			if (code == OAuthConstants.HTTP_UNAUTHORIZED) {

				LOG.info("Authorization server expects Basic authentication");
				// Add Basic Authorization header
				post.addHeader(OAuthConstants.AUTHORIZATION, getBasicAuthorizationHeader(oauthDetails.getClientId(), oauthDetails.getClientSecret()));
				LOG.info("Retry with client credentials");
				post.releaseConnection();
				response = client.execute(post);
				code = response.getStatusLine().getStatusCode();

				if (code == 401 || code == 403) {
					LOG.info("Could not authenticate using client credentials.");
					throw new RuntimeException("Could not retrieve access token for client: " + oauthDetails.getClientId());

				}

			}
			Map map = handleResponse(response);
			//accessToken = map.get(OAuthConstants.ACCESS_TOKEN);

			LOG.info("NeigouOAuthUtils--getAccessToken map======" + map.toString());

			JSONObject tokenJsonData = JSONObject.parseObject((String) map.get("Data"));
			if (tokenJsonData.containsKey("access_token")) {
				accessToken = (String) tokenJsonData.get("access_token");
			}

		} catch (ClientProtocolException e) {
			doCatchException(e);
		} catch (IOException e) {
			doCatchException(e);
		}

		LOG.info("NeigouOAuthUtils--getAccessToken end ======");
		return accessToken;
	}

	//创建公司
	public static String CreateCompany(NeigouOAuth2Details oauthDetails, String accessToken, JSONObject companyJsonData) {


		LOG.info("NeigouOAuthUtils--CreateCompany======");

		LOG.info("NeigouOAuthUtils--CreateCompany 使用 accessToken======" + accessToken);

		LOG.info("NeigouOAuthUtils--CreateCompany 创建公司信息:" + companyJsonData.toJSONString());

		//创建公司 url
		//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/v1/Standard/Company/sync");
		HttpPost post = new HttpPost(oauthDetails.getCreatecompany_url());
		post.setHeader("AUTHORIZATION", "Bearer " + accessToken);

		//String clientId = oauthDetails.getClientId();
		//String clientSecret = oauthDetails.getClientSecret();
		String scope = oauthDetails.getScope();

		List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
			
			
			/*JSONObject companyJsonData=new JSONObject();
			companyJsonData.put("external_company_id", "cjqt_20171127");
			companyJsonData.put("company_name", "超级前台_20171127");
			companyJsonData.put("company_name_short", "超级前台");
			companyJsonData.put("contacts_phone", "13066855659");
			companyJsonData.put("contacts_name", "青章银");		
			companyJsonData.put("contacts_email", "2290989798@qq.com");*/

		//parametersBody.add(new BasicNameValuePair("external_company_id","cjqt_20171127"));
		//parametersBody.add(new BasicNameValuePair("company_name","超级前台_20171127"));
		//parametersBody.add(new BasicNameValuePair("contacts_phone", "13066855659"));
		//parametersBody.add(new BasicNameValuePair("contacts_email", "2290989798@qq.com"));
		parametersBody.add(new BasicNameValuePair("data", companyJsonData.toJSONString()));


		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		String createCompanyResult = null;
		try {
			post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));

			response = client.execute(post);
			int code = response.getStatusLine().getStatusCode();
			if (code == OAuthConstants.HTTP_UNAUTHORIZED) {
				LOG.info("Authorization server expects Basic authentication");
				// Add Basic Authorization header
				//post.addHeader(OAuthConstants.AUTHORIZATION,getBasicAuthorizationHeader(oauthDetails.getClientId(),oauthDetails.getClientSecret()));
				LOG.info("Retry with client credentials");
				post.releaseConnection();
				response = client.execute(post);
				code = response.getStatusLine().getStatusCode();
				if (code == 401 || code == 403) {
					LOG.info("Could not authenticate using client credentials.");
					throw new RuntimeException(
							"Could not retrieve access token for client: "
									+ oauthDetails.getClientId());

				}

			}
			Map map = handleResponse(response);
			createCompanyResult = (String) map.get("Result");

			LOG.info("NeigouOAuthUtils--CreateCompany createCompanyResult======" + createCompanyResult);
			LOG.info("NeigouOAuthUtils--CreateCompany map======" + map.toString());

			if (!createCompanyResult.equals("true")) {
				LOG.info("NeigouOAuthUtils--CreateCompany 失败  将用默认公司");
			}

			//JSONObject tokenJsonData=(JSONObject)map.get("Data");
			//accessToken=(String)tokenJsonData.get("access_token");
			//String ss=EntityUtils.toString(response.getEntity());
			//LOG.info(ss);

		} catch (ClientProtocolException e) {
			doCatchException(e);
		} catch (IOException e) {
			doCatchException(e);
		}


		return createCompanyResult;
	}

	//创建用户
	   /* public static String CreateUser(NeigouOAuth2Details oauthDetails,String accessToken,String company_id,String user_id) throws Exception{
			
			LOG.info("NeigouOAuthUtils--CreateUser start ======");
			
			LOG.info("NeigouOAuthUtils--CreateUser user_id======"+user_id);
			
			LOG.info("NeigouOAuthUtils--CreateUser 使用 accessToken======"+accessToken);
	    	
			//创建公司 url
			//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/sync");
			                               //http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/sync
			HttpPost post = new HttpPost(oauthDetails.getCreateuser_url());
			post.setHeader("AUTHORIZATION", "Bearer "+accessToken);
			
			//String clientId = oauthDetails.getClientId();
			//String clientSecret = oauthDetails.getClientSecret();

			
			String createUserResult = null;
			JSONObject jsonData=new JSONObject();
			jsonData.put("external_user_id", user_id);//必录
			jsonData.put("external_company_id", company_id);//必录
			jsonData.put("AUTHORIZATION", "Bearer "+accessToken);//必录
			//jsonData.put("external_company_id", "cjqt_20171127");//必录
			//jsonData.put("mobile", user_id);
			//jsonData.put("mail", "2290989798@qq.com");			
	
			LOG.info("NeigouOAuthUtils--CreateUser BasicNameValuePair data======"+jsonData.toJSONString());
			

			Map<String,String> map=new HashMap<String,String>();
			map.put("external_user_id", user_id);
			map.put("external_company_id", company_id);
			
			String jsonMapStr=JSONObject.toJSONString(map);
			String jsonSendMsg="data="+jsonMapStr;
			
			String result=HttpKit.post(oauthDetails.getCreateuser_url(), jsonSendMsg);
			
			map = handleResponseJson(result);
			createUserResult = (String)map.get("Result");
			
			LOG.info("NeigouOAuthUtils--CreateUser createUserResult======"+createUserResult);	
			LOG.info("NeigouOAuthUtils--CreateUser map======"+map.toString());	
			
			if(!createUserResult.equals("true")){
				LOG.info("NeigouOAuthUtils--CreateUser 创建用户失败");	
			}
			

			LOG.info("NeigouOAuthUtils--CreateUser end ======");
			return createUserResult;
		}*/


	//创建用户
	public static String CreateUser(NeigouOAuth2Details oauthDetails, String accessToken, String company_id, AppUser userEn) {

		LOG.info("NeigouOAuthUtils--CreateUser start ======");

		LOG.info("NeigouOAuthUtils--CreateUser user_id======" + userEn.getUserMobile());

		LOG.info("NeigouOAuthUtils--CreateUser 使用 accessToken======" + accessToken);

		//创建公司 url
		//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/sync");
		//http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/sync
		HttpPost post = new HttpPost(oauthDetails.getCreateuser_url());
		post.setHeader("AUTHORIZATION", "Bearer " + accessToken);

		//String clientId = oauthDetails.getClientId();
		//String clientSecret = oauthDetails.getClientSecret();
		String scope = oauthDetails.getScope();

		List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();


		JSONObject jsonData = new JSONObject();
		jsonData.put("external_user_id", userEn.getUserMobile());//必录
		jsonData.put("external_company_id", company_id);//必录

		//用于内购显示 你好,** 使用微信昵称 不用真实名称
		if (StringUtils.isNotEmpty(userEn.getNickName())) {
			jsonData.put("nickname", userEn.getNickName());
			jsonData.put("name", userEn.getNickName());
		} else {
			jsonData.put("nickname", "超级前台用户");
			jsonData.put("name", "超级前台用户");
		}

		//jsonData.put("mobile", user_id);
		//jsonData.put("mail", "2290989798@qq.com");

		LOG.info("NeigouOAuthUtils--CreateUser BasicNameValuePair data======" + jsonData.toJSONString());

		parametersBody.add(new BasicNameValuePair("data", jsonData.toJSONString()));

		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		String createUserResult = null;
		try {
			post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));

			response = client.execute(post);
			int code = response.getStatusLine().getStatusCode();
			if (code == OAuthConstants.HTTP_UNAUTHORIZED) {
				LOG.info("Authorization server expects Basic authentication");
				LOG.info("Retry with client credentials");
				post.releaseConnection();
				response = client.execute(post);
				code = response.getStatusLine().getStatusCode();
				if (code == 401 || code == 403) {
					LOG.info("Could not authenticate using client credentials.");
					throw new RuntimeException("Could not retrieve access token for client: " + oauthDetails.getClientId());
				}

			}

			////{"Result":"true","ErrorMsg":"operate success","Data":{"member_id":"39312"}}
			Map map = handleResponse(response);
			createUserResult = (String) map.get("Result");

			LOG.info("NeigouOAuthUtils--CreateUser createUserResult======" + createUserResult);
			LOG.info("NeigouOAuthUtils--CreateUser map======" + map.toString());

			if (!createUserResult.equals("true")) {
				LOG.info("NeigouOAuthUtils--CreateUser 创建用户失败");
			}


		} catch (ClientProtocolException e) {
			doCatchException(e);
		} catch (IOException e) {
			doCatchException(e);
		}

		LOG.info("NeigouOAuthUtils--CreateUser end ======");
		return createUserResult;
	}


	//创建用户
	public static String getUserMessage(NeigouOAuth2Details oauthDetails, String accessToken, ReplayContentDao replayContentDao, WeChatApiManager weChatApiManager) {

		LOG.info("NeigouOAuthUtils--CreateUser start ======");


		LOG.info("NeigouOAuthUtils--CreateUser 使用 accessToken======" + accessToken);

		//创建公司 url
		//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/sync");
		//http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/sync
		HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/V1/Standard/Message/getUserMessage");
		post.setHeader("AUTHORIZATION", "Bearer " + accessToken);

		//String clientId = oauthDetails.getClientId();
		//String clientSecret = oauthDetails.getClientSecret();
		String scope = oauthDetails.getScope();

		List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();


		JSONObject jsonData = new JSONObject();
		jsonData.put("last_message_id", "18803");
		//jsonData.put("external_user_id", user_id);//必录
		//jsonData.put("external_company_id", company_id);//必录
		//jsonData.put("external_company_id", "cjqt_20171127");//必录
		//jsonData.put("mobile", user_id);
		//jsonData.put("mail", "2290989798@qq.com");

		LOG.info("NeigouOAuthUtils--CreateUser BasicNameValuePair data======" + jsonData.toJSONString());

		parametersBody.add(new BasicNameValuePair("data", jsonData.toJSONString()));

		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		String createUserResult = null;
		try {
			post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));

			response = client.execute(post);
			int code = response.getStatusLine().getStatusCode();
			if (code == OAuthConstants.HTTP_UNAUTHORIZED) {
				LOG.info("Authorization server expects Basic authentication");
				LOG.info("Retry with client credentials");
				post.releaseConnection();
				response = client.execute(post);
				code = response.getStatusLine().getStatusCode();
				if (code == 401 || code == 403) {
					LOG.info("Could not authenticate using client credentials.");
					throw new RuntimeException("Could not retrieve access token for client: " + oauthDetails.getClientId());
				}

			}

			////{"Result":"true","ErrorMsg":"operate success","Data":{"member_id":"39312"}}
			Map map = handleResponse(response);
			createUserResult = (String) map.get("Result");

			LOG.info("NeigouOAuthUtils--CreateUser createUserResult======" + createUserResult);
			LOG.info("NeigouOAuthUtils--CreateUser map======" + map.toString());


			String title = "";
			String OrderSn = "";
			String OrderStatus = "";
			String remark = "";
			String orderDetailUrl = "";
			String external_user_id = "";
			JSONObject dataJsonData = JSONObject.parseObject((String) map.get("Data"));
			if (dataJsonData.containsKey("message_list")) {
				//String message_listStr=(String) dataJsonData.get("message_list");
				String message_listStr = ((com.alibaba.fastjson.JSONArray) dataJsonData.get("message_list")).get(0).toString();
				JSONObject message_listJson = JSONObject.parseObject(message_listStr);
				if (message_listJson.containsKey("external_user_id")) {
					external_user_id = (String) message_listJson.get("external_user_id");
					System.out.println("external_user_id===" + external_user_id);
				}


				if (message_listJson.containsKey("content")) {
					title = (String) message_listJson.get("content");
					System.out.println("title===" + title);
				}

				if (message_listJson.containsKey("extra_params")) {
					JSONObject extra_paramsJson = JSONObject.parseObject(message_listJson.getString("extra_params"));
					if (extra_paramsJson.containsKey("OrderSn")) {//订单编号
						OrderSn = extra_paramsJson.getString("OrderSn");
						System.out.println("OrderSn===" + OrderSn);
					}
					if (extra_paramsJson.containsKey("OrderStatus")) {//订单状态
						OrderStatus = extra_paramsJson.getString("OrderStatus");
						System.out.println("OrderStatus===" + OrderStatus);
					}
					if (extra_paramsJson.containsKey("remark")) {//备注
						remark = extra_paramsJson.getString("remark");
						System.out.println("remark===" + remark);
					}
					if (extra_paramsJson.containsKey("url")) {//详情url
						orderDetailUrl = extra_paramsJson.getString("url");
						System.out.println("orderDetailUrl===" + orderDetailUrl);
					}
				}
			}

			List<Map<String, Object>> templateList = replayContentDao.getWxTemplate(ElementConstant.TemplateType04, 0);
			if (!CollectionUtils.isEmpty(templateList)) {
				String templateId = (String) templateList.get(0).get("templateId");
				Map<String, String> paramMap = new HashMap<String, String>();

				//paramMap.put("openId", wxUser.getOpenId());
				//paramMap.put("developId", wxUser.getDevelopId());
				paramMap.put("templateId", templateId);
				paramMap.put("url", orderDetailUrl);
				paramMap.put("title", title + "\\n");
				paramMap.put("orderNum", OrderSn);
				paramMap.put("orderStateDesc", OrderStatus);
				paramMap.put("remark", remark);
				weChatApiManager.sendTemplateMsg03(paramMap);
			}

			if (!createUserResult.equals("true")) {
				LOG.info("NeigouOAuthUtils--CreateUser 创建用户失败");
			}


		} catch (ClientProtocolException e) {
			doCatchException(e);
		} catch (IOException e) {
			doCatchException(e);
		}

		LOG.info("NeigouOAuthUtils--CreateUser end ======");
		return createUserResult;
	}

	/**
	 * 创建用户登录使用的login_token
	 * 第三方用户唯一标识 （必填）
	 * 第三方用户所在公司唯一标识（非必填）
	 */
	public static String CreateLoginToken(NeigouOAuth2Details oauthDetails, String accessToken, String user_company_id, String user_id) {

		LOG.info("NeigouOAuthUtils--CreateLoginToken======");

		LOG.info("NeigouOAuthUtils--CreateLoginToken user_id======" + user_id);

		LOG.info("NeigouOAuthUtils--CreateLoginToken 使用 accessToken======" + accessToken);

		//创建公司 url
		HttpPost post = new HttpPost(oauthDetails.getCreatelogintoken_url());
		//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/V1/Standard/User/createLoginToken");
		post.setHeader("AUTHORIZATION", "Bearer " + accessToken);

		//String clientId = oauthDetails.getClientId();
		//String clientSecret = oauthDetails.getClientSecret();
		String scope = oauthDetails.getScope();

		List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();


		JSONObject jsonData = new JSONObject();
		jsonData.put("external_user_id", user_id);//以手机号 维度
		jsonData.put("external_company_id", user_company_id);//创建的公司id		


		LOG.info("NeigouOAuthUtils--CreateLoginToken BasicNameValuePair data======" + jsonData.toJSONString());
		parametersBody.add(new BasicNameValuePair("data", jsonData.toJSONString()));


		DefaultHttpClient client = new DefaultHttpClient();
		HttpResponse response = null;
		String createCompanyResult = null;
		try {
			post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));

			response = client.execute(post);
			int code = response.getStatusLine().getStatusCode();
			if (code == OAuthConstants.HTTP_UNAUTHORIZED) {
				LOG.info("Authorization server expects Basic authentication");
				// Add Basic Authorization header
				//post.addHeader(OAuthConstants.AUTHORIZATION,getBasicAuthorizationHeader(oauthDetails.getClientId(),oauthDetails.getClientSecret()));
				LOG.info("Retry with client credentials");
				post.releaseConnection();
				response = client.execute(post);
				code = response.getStatusLine().getStatusCode();
				if (code == 401 || code == 403) {
					LOG.info("Could not authenticate using client credentials.");
					throw new RuntimeException(
							"Could not retrieve access token for client: "
									+ oauthDetails.getClientId());

				}

			}
			Map map = handleResponse(response);
			//createCompanyResult = (String)map.get("Result");

			//JSONObject tokenJsonData=(JSONObject)map.get("Data");
			//createCompanyResult=(String)tokenJsonData.get("login_token");


			JSONObject tokenJsonData = JSONObject.parseObject((String) map.get("Data"));
			if (tokenJsonData.containsKey("login_token")) {
				createCompanyResult = (String) tokenJsonData.get("login_token");
			}


			//String ss=EntityUtils.toString(response.getEntity());
			//LOG.info(ss);

		} catch (ClientProtocolException e) {
			doCatchException(e);//token 失败其他都会有问题 这抛异常
		} catch (IOException e) {
			doCatchException(e);
		}

		return createCompanyResult;
	}


	public static void doCatchException(Exception e) {

		LOG.error("doCatchException 异常信息如下==============");
		LOG.error(LogExceptionStackUtil.LogExceptionStack(e));
		throw new RuntimeException("请检查网络或稍后再试");
	}

	/**
	 * 使用login_token登录用户
	 * 第三个url 得到   login_token 构造url登录
	 */

	public static String CreateLoginURL(NeigouOAuth2Details oauthDetails, String login_token, String furl) {


		String params = "surl=" + oauthDetails.getSurl();
		//params+="&furl='http://test.neigou.com/?err=NG_ERRCODE'";
		//params+="&furl=http://wx.palmnest.com/super_reception/wechat/neigou/neigouFailJump?err=NG_ERRCODE?appid=wxffe70d6b42696497";
		//params+="&furl=http://localhost:8080/super_reception/wechat/neigou/neigouFailJump?err=NG_ERRCODE?appid=wxffe70d6b42696497";
		params += "&furl=" + furl;

		params += "&login_token=" + login_token;
		params += "&force=true";//强制切换公司

		//创建公司 url
		//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/v1/Standard/Web/gateway?"+params);
		HttpPost post = new HttpPost(oauthDetails.getGateway_url() + "?" + params);


		return post.getURI().toString();
	}


	/**
	 * 用户登录网关
	 * 第一个Url
	 * 已经在图标上配置了 不用这个方法
	 */
	public static String getFirstJumpUrl(NeigouOAuth2Details oauthDetails, String company_id, String user_mobile_id, String furl) {

		String params = "surl=" + oauthDetails.getSurl();
		params += "&furl=" + furl;
		params += "&user=" + user_mobile_id;
		params += "&company=" + company_id;
		params += "&client_id=" + oauthDetails.getClientId();

		//HttpPost post = new HttpPost("http://openapi.test.neigou.com/ChannelInterop/v1/Standard/Web/gateway?"+params);
		HttpPost post = new HttpPost(oauthDetails.getGateway_url() + "?" + params);

		return post.getURI().toString();
	}


	public static Map handleResponse(HttpResponse response) {
		String contentType = OAuthConstants.JSON_CONTENT;
		//if (response.getEntity().getContentType() != null) {
		//contentType = response.getEntity().getContentType().getValue();
		//}
		if (contentType.contains(OAuthConstants.JSON_CONTENT)) {
			return handleJsonResponse(response);
		} else if (contentType.contains(OAuthConstants.URL_ENCODED_CONTENT)) {
			return handleURLEncodedResponse(response);
		} else if (contentType.contains(OAuthConstants.XML_CONTENT)) {
			return handleXMLResponse(response);
		} else {
			// Unsupported Content type
			throw new RuntimeException("Cannot handle " + contentType + " content type. Supported content types include JSON, XML and URLEncoded");
		}

	}

	public static Map handleResponseJson(String json) {


		Map<String, String> oauthLoginResponse = null;
		oauthLoginResponse = JSONObject.parseObject(json, new TypeReference<Map<String, String>>() {
		});

		return oauthLoginResponse;


	}

	public static Map handleJsonResponse(HttpResponse response) {
		Map<String, String> oauthLoginResponse = null;
		//Map<String, Object> oauthLoginResponse = null;
		String contentType = response.getEntity().getContentType().getValue();
		try {
			//oauthLoginResponse = (Map<String, String>) new JSONParser().parse(EntityUtils.toString(response.getEntity()));

			JSONObject jsonObjectTemp = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
			oauthLoginResponse = JSONObject.parseObject(jsonObjectTemp.toJSONString(), new TypeReference<Map<String, String>>() {
			});

			//JSONObject jsonObjectTemp=JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
			//oauthLoginResponse = JSONObject.parseObject(jsonObjectTemp.toJSONString(), Map.class);

		} catch (ParseException e) {
			doCatchException(e);
		} catch (IOException e) {
			doCatchException(e);
		} catch (RuntimeException e) {
			doCatchException(e);
		}

		LOG.info("********** Response Received **********");
		//for (Map.Entry<String, String> entry : oauthLoginResponse.entrySet()) {
		//		LOG.info(String.format("  %s = %s", entry.getKey(),entry.getValue()));
		//}
		return oauthLoginResponse;
	}

	public static Map handleURLEncodedResponse(HttpResponse response) {
		Map<String, Charset> map = Charset.availableCharsets();
		Map<String, String> oauthResponse = new HashMap<String, String>();
		Set<Map.Entry<String, Charset>> set = map.entrySet();
		Charset charset = null;
		HttpEntity entity = response.getEntity();

		LOG.info("********** Response Received **********");

		for (Map.Entry<String, Charset> entry : set) {
			LOG.info(String.format("  %s = %s", entry.getKey(),
					entry.getValue()));
			if (entry.getKey().equalsIgnoreCase(HTTP.UTF_8)) {
				charset = entry.getValue();
			}
		}

		try {
			List<NameValuePair> list = URLEncodedUtils.parse(
					EntityUtils.toString(entity), Charset.forName(HTTP.UTF_8));
			for (NameValuePair pair : list) {
				LOG.info(String.format("  %s = %s", pair.getName(),
						pair.getValue()));
				oauthResponse.put(pair.getName(), pair.getValue());
			}

		} catch (IOException e) {
			doCatchException(e);
		}

		return oauthResponse;
	}

	public static Map handleXMLResponse(HttpResponse response) {
		Map<String, String> oauthResponse = new HashMap<String, String>();
		try {

			String xmlString = EntityUtils.toString(response.getEntity());
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder db = factory.newDocumentBuilder();
			InputSource inStream = new InputSource();
			inStream.setCharacterStream(new StringReader(xmlString));
			Document doc = db.parse(inStream);

			LOG.info("********** Response Receieved **********");
			parseXMLDoc(null, doc, oauthResponse);
		} catch (Exception e) {
			doCatchException(e);
		}
		return oauthResponse;
	}

	public static void parseXMLDoc(Element element, Document doc,
								   Map<String, String> oauthResponse) {
		NodeList child = null;
		if (element == null) {
			child = doc.getChildNodes();

		} else {
			child = element.getChildNodes();
		}
		for (int j = 0; j < child.getLength(); j++) {
			if (child.item(j).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
				org.w3c.dom.Element childElement = (org.w3c.dom.Element) child
						.item(j);
				if (childElement.hasChildNodes()) {
					LOG.info(childElement.getTagName() + " : "
							+ childElement.getTextContent());
					oauthResponse.put(childElement.getTagName(),
							childElement.getTextContent());
					parseXMLDoc(childElement, null, oauthResponse);
				}

			}
		}
	}

	public static String getAuthorizationHeaderForAccessToken(String accessToken) {
		return OAuthConstants.BEARER + " " + accessToken;
	}

	public static String getBasicAuthorizationHeader(String username,
													 String password) {
		return OAuthConstants.BASIC + " "
				+ encodeCredentials(username, password);
	}

	public static String encodeCredentials(String username, String password) {
		String cred = username + ":" + password;
		String encodedValue = null;
		byte[] encodedBytes = Base64.encodeBase64(cred.getBytes());
		encodedValue = new String(encodedBytes);
		LOG.info("encodedBytes " + new String(encodedBytes));

		byte[] decodedBytes = Base64.decodeBase64(encodedBytes);
		LOG.info("decodedBytes " + new String(decodedBytes));

		return encodedValue;

	}

	public static boolean isValidInput(NeigouOAuth2Details input) {


		if (input == null) {
			return false;
		}

		String grantType = input.getGrantType();

		if (!isValid(grantType)) {
			LOG.info("Please provide valid value for grant_type");
			return false;
		}

		if (!isValid(input.getAuthenticationServerUrl())) {
			LOG.info("Please provide valid value for authentication server url");
			return false;
		}

		if (grantType.equals(OAuthConstants.GRANT_TYPE_PASSWORD)) {
			if (!isValid(input.getUsername()) || !isValid(input.getPassword())) {
				LOG.info("Please provide valid username and password for password grant_type");
				return false;
			}
		}

		if (grantType.equals(OAuthConstants.GRANT_TYPE_CLIENT_CREDENTIALS)) {
			if (!isValid(input.getClientId()) || !isValid(input.getClientSecret())) {
				LOG.info("Please provide valid client_id and client_secret for client_credentials grant_type");
				return false;
			}
		}

		LOG.info("Validated Input");
		return true;

	}

	public static boolean isValid(String str) {
		return (str != null && str.trim().length() > 0);
	}

}
