package com.eactive.eai.rms.common.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eactive.eai.rms.common.base.OnlBaseService;
import com.eactive.eai.rms.common.context.MonitoringContext;

@Service("monitoringSyncAgent")
public class MonitoringSyncAgent extends OnlBaseService {
	
	@Autowired
	private MonitoringContext monitoringContext;

	
	public MonitoringSyncAgent(){
		
	}
    public Map<String, String> sync(String url, Map paramMap) throws Exception{
    	//List<Map<String,String>> ipList = null;
    	Map<String, String> ips = new HashMap<>();
    	try{  		
			ips = new HashMap<>(monitoringContext.getPortMapper());
    		if(ips.size() <1)
    			throw new Exception();
			//ipList = eaiServerInfoService.getHostServerIpList();
    	}catch(Exception e){
    		throw new Exception("모니터링 IP 정보가 없음");
    	}

		//로컬 IP 주소
		//String hostIp = InetAddress.getLocalHost().getHostAddress();
		StringBuffer sb = new StringBuffer();
		
		for(String m : ips.keySet()){
			
			String ip = m;
			String port = ips.get(m);

			String result="";

			if(port == null)
				continue;
				//throw new BizException("모니터링 프로퍼트에 WEBSERVERPORT가 없습니다");
			
			try{
				result = callService(ip,port, url, paramMap);
				 if(result.indexOf("success") <0)
					 throw new Exception("Monitoring Sync 실패");
				 else{
					 sb.append(ip +"=success; ");
					 
				 }
			}catch(Exception e){
				sb.append(ip +"=failed; ");
			}
			
			
		}


		Map<String, String> retMap = new HashMap<>();
		retMap.put("result", sb.toString());	
		return retMap;

	}
    public Map<String, String> targetSync(String url, Map paramMap) throws Exception{
    	//List<Map<String,String>> ipList = null;
    	Map<String, String> ips = new HashMap<>();
    	try{  		
			ips = new HashMap<>(monitoringContext.getPortMapper());;
    		if(ips.size() < 1)
    			throw new Exception();
			//ipList = eaiServerInfoService.getHostServerIpList();
    	}catch(Exception e){
    		throw new Exception("모니터링 IP 정보가 없음");
    	}

		//로컬 IP 주소
		String hostIp = InetAddress.getLocalHost().getHostAddress();
		StringBuffer sb = new StringBuffer();
		
		for(String m : ips.keySet()){
			
			String ip = m;
			String port = ips.get(m);
		
			String result="";
			//TO-DO
			//current IP 는 skip 로직 추가 할것.
			if(ip.equals(hostIp)) continue;
			if(port == null)	continue;
				//throw new BizException("모니터링 프로퍼트에 WEBSERVERPORT가 없습니다");		
			
			try{
				result =callService(ip,port, url, paramMap);
				 if(result.indexOf("success") <0)
					 throw new Exception("Monitoring Sync 실패-"+result);
				 else{
					 sb.append(ip +"=success; ");
					 
				 }
			}catch(Exception e){
				sb.append(ip +"=failed; "+e.getMessage());
			}
			
			
		}


		Map<String, String> retMap = new HashMap<>();
		retMap.put("result", sb.toString());	
		return retMap;

	}    
	public String callService(String ip, String port, String targetUrl, Map<String,String> paramMap) throws Exception{
		int timeout = 5*1000;
		String encode = "MS949";

		String url = "http://"+ip+":"+port+targetUrl;	
	
		PostMethod method = new PostMethod(url);
		method.getParams().setSoTimeout(timeout);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
											new DefaultHttpMethodRetryHandler(1,false));
		//method.setFollowRedirects(true);
		HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager());
	 	mclient.getParams().setContentCharset(encode);


    	for(String key : paramMap.keySet()){
    		String value = paramMap.get(key);
    		method.addParameter(key, new String(value.getBytes(encode)));
    	}
    	String responseMessage = "";
    	try{
	    	int status = mclient.executeMethod(method);	
	    	if(status != 200)
	    		throw new Exception("status-"+status+" fail");
	    	responseMessage = getResponse(method); 
	    	//responseMessage = new String(method.getResponseBody());      
	        //System.out.println(responseMessage);
    	}catch(Exception e){
    		logger.error("sync failed", e);
    		responseMessage="error("+e.toString()+")";
    	}finally{
    		method.releaseConnection();
    	}
    	return responseMessage;
	}
	private String getResponse( PostMethod method ) throws Exception{
		InputStream instream  = null;
		try {
			instream = method.getResponseBodyAsStream();
            if(instream != null){
            	long contentLength = method.getResponseContentLength();
                ByteArrayOutputStream outstream = new ByteArrayOutputStream(contentLength <= 0L ? 4096 : (int)contentLength);
                byte buffer[] = new byte[4096];
                int len;
                while((len = instream.read(buffer)) > 0) {
                    outstream.write(buffer, 0, len);
                }
                outstream.close();
                return new String(outstream.toByteArray());
            }else{
            	throw new Exception("http receive data null");
            }
		}finally{
			if ( instream != null ) try {instream.close();} catch (IOException e) {}
		}
	}	

	public String callService(String targetUrl, HashMap<String,String> paramMap) throws Exception{
		int timeout = 5*1000;
		String encode = "MS949";

		PostMethod method = new PostMethod(targetUrl);
		method.getParams().setSoTimeout(timeout);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
											new DefaultHttpMethodRetryHandler(1,false));
		//method.setFollowRedirects(true);
		HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager());
	 	mclient.getParams().setContentCharset(encode);


    	for(String key : paramMap.keySet()){
    		String value = paramMap.get(key);
    		method.addParameter(key, new String(value.getBytes(encode)));
    	}
    	String responseMessage = "";
    	try{
	    	int status = mclient.executeMethod(method);	
	    	if(status != 200)
	    		throw new Exception("fail");
	    	responseMessage = getResponse(method); 
	    	//responseMessage = new String(method.getResponseBody());      
    	}catch(Exception e){
    		responseMessage="error("+e.getMessage()+")";
    	}finally{
    		method.releaseConnection();
    	}
    	return responseMessage;
	}
	
	public String callService2(String targetUrl, Map<String,String> paramMap) throws Exception{
		int timeout = 5*1000;
		String encode = "UTF-8";

		PostMethod method = new PostMethod(targetUrl);
		method.getParams().setSoTimeout(timeout);
		method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
											new DefaultHttpMethodRetryHandler(1,false));
		//method.setFollowRedirects(true);
		HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager());
		mclient.getParams().setContentCharset(encode);

    	for(String key : paramMap.keySet()){
    		String value = paramMap.get(key);
    		method.addParameter(key, value);
    	}
    	String responseMessage = "";
    	try{
	    	int status = mclient.executeMethod(method);	
	    	if(status != 200)
	    		throw new Exception("fail");
	    	responseMessage = getResponse(method); 
	    	//responseMessage = new String(method.getResponseBody());      
    	}catch(Exception e){
    		responseMessage="error("+e.getMessage()+")";
    	}finally{
    		method.releaseConnection();
    	}
    	return responseMessage;
	}
}
