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

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

public class HttpClientUploadUtil {
	private static final Logger logger = Logger.getLogger(HttpClientUploadUtil.class);
	private static String encoding ="utf-8";
	private static ContentType CONTENT_TYPE = ContentType.MULTIPART_FORM_DATA.withCharset(encoding);

	private static MultipartEntityBuilder makeMultipartData(HashMap<String,String> multipartData){
		MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
		reqEntity.setCharset(Charset.forName(encoding));
		for(String key : multipartData.keySet()){
			reqEntity.addTextBody(key, multipartData.get(key),CONTENT_TYPE);
		}
		
		return reqEntity;
	} 
	public static String post(String url, HashMap<String,String> params) throws Exception{
		CloseableHttpClient httpclient = null ;
		try {
			httpclient = HttpClients.createDefault();
	        List<NameValuePair> nameValues = new ArrayList<>();
	        for(String key : params.keySet()){
	        	nameValues.add(new BasicNameValuePair(key,params.get(key))); 
	        }
	        URIBuilder uriBuilder = new URIBuilder(url);
	        uriBuilder.addParameters(nameValues);
	    	HttpPost httppost = new HttpPost(uriBuilder.build());
	        HttpResponse response = httpclient.execute(httppost);
	        HttpEntity entity = response.getEntity();
	        
	        String str = EntityUtils.toString(entity);
	
			return str;
        } catch (Exception e) {
        	logger.error(e.getMessage(),e);
        	throw e;

        } finally {
        	 if (httpclient != null){ try{httpclient.close();}catch(Exception e){}}
        }

	}
	
	public static String upload(String url, HashMap<String,String> params, MultiValueMap<String, Object> multipartParams) throws Exception{
		
		url += "?";
		StringBuilder sb = new StringBuilder();
		params.forEach((k, v) -> sb.append(k).append("=").append(v).append("&"));
		url += sb.toString();
		
		/** For Multipart Request **/
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.MULTIPART_FORM_DATA);
		org.springframework.http.HttpEntity<MultiValueMap<String, Object>> requestEntity = new org.springframework.http.HttpEntity<>(multipartParams, headers);
		
        try {
            
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, requestEntity, String.class);
            
            String str = responseEntity.getBody();
			
	        JSONObject obj = (JSONObject) JSONValue.parse(str);
	        if (obj == null){
	        	throw new Exception("http response error json parsing is null");
	        }
	        String jsonStatus = (String)obj.get("status");
	        if (jsonStatus == null){
	        	throw new Exception("http response error json status is null");
	        }
	        if (!"success".equals(jsonStatus)){
	        	throw new Exception("http response error json status is " + jsonStatus + " json data " + str );
	        }
			
			return str;
        } catch (Exception e) {
        	logger.error(e.getMessage(),e);
        	throw e;
        }
        
	}
	public static MultiValueMap<String, Object> buildFileUploadData(String selectFolder, String cmFolder) throws Exception{

		MultiValueMap<String, Object> multipartParams = new LinkedMultiValueMap<>();
		File file = new File(selectFolder + File.separator + cmFolder);
	
		File[] files = file.listFiles();
		if (files == null) {
			throw new Exception("folder("+selectFolder + File.separator + cmFolder+") 존재하지 않음");
		}
		for(File f : files){
			if (f.isDirectory()){
				String folderName = f.getName();
				File sub = new File(f.getAbsolutePath());
				File[] subfiles = sub.listFiles();
				if (subfiles == null){
					throw new Exception("sub folder("+f.getAbsolutePath()+") 존재하지 않음");
				}
				for(File sf : subfiles ){
					if (sf.isFile()){
						String name = folderName+"_"+sf.getName();
						String data = read(sf.getAbsolutePath());
						multipartParams.add(name, data);
						logger.debug("buildFileUploadData : name = " + name + ", data =" +data);
					}
				}
			}
		}
		return multipartParams;
	}

	
	private static String read(String filePath){
		FileReader fr = null;
		BufferedReader br = null;
		String lbuff =null;
        StringBuffer sb = new StringBuffer();
        try {
        	fr = new FileReader(filePath);
        	br = new BufferedReader(fr);
			while ((lbuff = br.readLine()) != null) {
				sb.append(lbuff).append("\n");
	        }
        }catch(Exception ex) {
			//ex.printStackTrace();
        	//취약점소스 수정 2020.08.24
        	logger.error(" error", ex); 
		}
		finally {
			if(br != null){
			  try{br.close();}catch(Exception e){}
			 }
			if(fr != null){
				try{fr.close();}catch(Exception e){}
			}
		}
		return sb.toString();
	}
//	public static void main(String[] args) throws Exception{  //취약점소스 수정 2020.08.26
//		String url           = "http://localhost:30711/monitoring/cmFileUpload.file";
//		String selectFolder  = "c:/fslog/eai/cm";    //로컬 검색 폴더
//		String cmFolder      = "20191029235959_S010795_A_TXT";//CM schedule folder
		
		
//		HashMap<String,String> multipartParams = buildFileUploadData( selectFolder, cmFolder);
//
//		HashMap<String,String> params = new HashMap<String,String>();
//		params.put("cmFolder", cmFolder);
//		
//		System.out.println(upload(url,params,multipartParams));
		
		
//		System.out.println(post(url, new HashMap(){{put("cmd","select");}}) );
		
//	}

}
