package incheon.res.rdm.com.levy;


import incheon.res.rdm.com.levy.stub.DefaultMessage;
import incheon.res.rdm.com.levy.vo.InputVO;
import incheon.res.rdm.com.levy.vo.LevyOutputVO;
import incheon.res.rdm.com.levy.vo.OutputVO;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.egovframe.rte.fdl.property.EgovPropertyService;
import org.springframework.stereotype.Component;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Random;

@Component("LevyUtil")
public class LevyUtil {
	
    protected Log log = LogFactory.getLog(this.getClass());
    
    @Resource(name = "propertiesService")
    protected EgovPropertyService propertiesService;

	/**
	 * 전송할 Message를 생성한다.
	 */
	public String buildXml(InputVO inVO) throws Exception {
		String outs = "";
		outs += "<root>";
		outs += "<enis_service_data>";
		Field[] fields = inVO.getClass().getDeclaredFields();
		for( int i=0; i<fields.length; i++ ) {
			String name = fields[i].getName();
			String value = "";
			if( inVO.getClass().getDeclaredField( fields[i].getName()).get(inVO ) != null){
				value = inVO.getClass().getDeclaredField( fields[i].getName()).get(inVO ).toString() ;
			}
			outs += "<"+name+">"+ value +"</"+name+">";
		}
		outs += "</enis_service_data>";
		outs += "</root>";


		return outs;

	}

	/**
	 * 웹서비스의 리턴결과를 VO에 담는다.
	 */
	public LevyOutputVO getResultVO(DefaultMessage resMessage, OutputVO vo) throws Exception{

		String headerString = new String(resMessage.getHeader());
		String bodyString = new String(resMessage.getBody(), "utf-8");

		String resultCd = "", resultMsg = "";

		log.error("headerString ----------------------------------"+headerString);
		log.error("bodyString ------------------------------------"+bodyString);

		Document decodedMsgDoc = getDocument(bodyString);
		Element eleFinal = decodedMsgDoc.getDocumentElement();
		NodeList nlFinal = eleFinal.getElementsByTagName(vo.getTag());

		NodeList nodeList = nlFinal.item(0).getChildNodes();
		String NodeValue = "";
		for(int i=0; i<nodeList.getLength(); i++ ) {
			NodeValue = "";
			try{
				NodeValue = nodeList.item(i).getFirstChild().getNodeValue();
			}catch(DOMException e){
				log.error(e.getMessage());
			}catch(Exception e){
				log.error(e.getMessage());
			}
			//jdk 1.5
			//vo.getClass().getDeclaredField( nodeList.item(i).getNodeName() ).set(vo, nodeList.item(i).getTextContent() );
			vo.getClass().getDeclaredField( nodeList.item(i).getNodeName() ).set(vo, NodeValue );
		}

		LevyOutputVO outputVO = (LevyOutputVO)vo;
		if(outputVO.getResult() == null) outputVO.setResult("");
		if(outputVO.getResult().indexOf("100") > 0)	outputVO.setResultCd("100");
		else outputVO.setResultCd("900");
		outputVO.setResultMsg(outputVO.getResult());


		return outputVO;
	}

	/**
	 * msgKey를 생성한다.
	 */
	public String getMsgKey(String ifId){
		String DATE_FORMAT = "yyyyMMddHHmmssSSS";
		SimpleDateFormat sdf = new SimpleDateFormat( DATE_FORMAT );
		Calendar cal = Calendar.getInstance();

		Random oRandom = new Random();

		long rndValue = 0;

		while(true){
			rndValue = Math.abs( oRandom.nextInt()*10000 );
			if(String.valueOf(rndValue).length()==6)
				break;
		}

		return ifId+sdf.format(cal.getTime())+rndValue;
	}

	/**
	 * Document 객체를 생성한다.
	 */
	public Document getDocument( String inputMsg ) throws Exception{
		Document doc = null ;

		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();

		InputSource inputSource = new InputSource(new StringReader( inputMsg ));
	    doc =docBuilder.parse( inputSource );

		return doc;
	}

	/**
	 * 자릿수 고정
	 */
	public byte[] toFixedLength(String data, int length)
	{
	    byte[] bdata = data.getBytes();
	    byte[] result = new byte[length];
	    System.arraycopy(bdata, 0, result, 0, bdata.length);
	    return result;
	}
}
