package nlib.restful.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import nlib.restful.service.DataApiReqVO;
import nlib.restful.service.DataApiResVO;
import nlib.restful.service.DataApiInterface;
import nlib.util.StringUtil;

/**
 * <pre>
 * @Class Name : DataApiRESTful.java
 * 
 * @Description : 통합자료관리시스템에 RESTful API를 통해 질의/응답을 처리한다.
 * 
 * 
 * @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
 *
 * </pre>
 *
 * @ ------------    --------    ---------------------------
 * @ 수정일                     수정자             수정내용
 * @ ------------    --------    ---------------------------
 * @ 2021. 6. 22.    KNKIM       최초 생성
 *
 * 
 * @author 이씨플라자 * DIGITALSHIP KNKIM
 * @since 2021. 6. 22.
 * @version 1.0
 *
 */
public class DataApiRESTful implements DataApiInterface {

	private static final Logger log = LoggerFactory.getLogger(DataApiRESTful.class);
	
	/* DataApi 접속 서버 정보 */ 
	@Value("#{properties['dataapi.server.ip']}") 
	private String DAPI_SERVER_IP;
	
	@Value("#{properties['dataapi.server.port']}") 
	private String DAPI_SERVER_PORT;
	
	@Value("#{properties['dataapi.server.protocol']}") 
	private String DAPI_SERVER_PROTOCOL;
	
	
	/**
	 * 조회 
	 * 
	 * @param reqVO
	 * @return
	 */
	public DataApiResVO get(DataApiReqVO reqVO) {
	
		return send(reqVO, HttpMethod.GET); 
	}
	
	/**
	 * 등록 
	 * 
	 * @param reqVO
	 * @return
	 */
	public DataApiResVO put(DataApiReqVO reqVO) {
		return send(reqVO, HttpMethod.PUT); 
	}
	
	/**
	 * 수정 
	 * 
	 * @param reqVO
	 * @return
	 */
	public DataApiResVO post(DataApiReqVO reqVO) {
		return send(reqVO, HttpMethod.POST); 
	}

	/**
	 * 삭제 
	 * 
	 * @param reqVO
	 * @return
	 */
	public DataApiResVO delete (DataApiReqVO reqVO) {
		return send(reqVO, HttpMethod.DELETE); 
	}

	/**
	 * 실제 RESTful API 서버로 요청을 전송하고, 응답받은 자료를 응답VO에 담아서 리턴한다.
	 * 
	 * @param reqVO
	 * @param method
	 * @return
	 */
	public DataApiResVO send(DataApiReqVO reqVO, HttpMethod method) {
	
    	DataApiResVO resVO = null;
    	
    	try {
        	//-----------------------------------
    		// 입력값 검증작업 
        	//-----------------------------------
    		resVO = DataApiInterface.checkReqCommonParams(reqVO);
        	if(resVO != null) return resVO;
        	if(method == null) return new DataApiResVO("ERR_NO_METHOD", "HTTP 요청 Method가 유효하지 않습니다."); 
    	
        	//-----------------------------------
        	// 폼 파라메터 생성 작업 
        	//-----------------------------------
    		HttpHeaders headers = new HttpHeaders();
    		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    		MultiValueMap<String, String> parameters = DataApiInterface.makeParamMap(reqVO); 
    		HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity(parameters, headers);
    		
        	//-----------------------------------
        	// 요청 처리 
        	//-----------------------------------
    		RestTemplate restTemplate = new RestTemplate();
    		String url = DAPI_SERVER_PROTOCOL + "://" + DAPI_SERVER_IP + ("80".equals(DAPI_SERVER_PORT) ? "" : ":" + DAPI_SERVER_PORT) + reqVO.getReqUrl();
    		log.debug("REQ URL : " + reqVO.getReqUrl());
    		
    		ResponseEntity<String> responseEntity = restTemplate.exchange(url, method, requestEntity, String.class);

        	//-----------------------------------
        	// 응답 처리  
        	//-----------------------------------
    	    HttpStatus statusCode = responseEntity.getStatusCode();
    		log.debug("RES StatusCode : " + statusCode);
    	    String resultXML = "";
    	    resultXML = responseEntity.getBody();
    	    log.debug("RES resultXML : " + resultXML);
    	    
    	    // 응답 자료 객체화 
    		resVO = DataApiInterface.convertXmlToResVO(resultXML);
    		
    		// 처리결과 코드 확인 
    		if(StringUtil.isEmpty(resVO.getResultCode())) {
        	    if (statusCode == HttpStatus.OK) {
        	    	resVO.setResultCode("S_HTTP_STATUS_OK");
        	    	resVO.setResultMessage("정상처리되었습니다.");
        	    } else {
        	    	resVO.setResultCode("E_STATUS_CODE_FAIL");
        	    	resVO.setResultMessage(String.format("처리에 실패하였습니다. (HTTP상태코드 : %s)", statusCode.toString()));
        	    }
    		}
    		
    		//log.debug("RES resVO : " + resVO);
    		
    	} catch(Exception e) {
    		e.printStackTrace();
    		return DataApiInterface.makeErrorRes("E_REQ_EXCEPTION", e.toString());
    	}
    	
	    return resVO;	
	}


}
