package com.eactive.eai.transformer.function.convert;

import java.math.BigDecimal;
import java.util.Stack;

import org.apache.commons.lang3.StringUtils;
import org.nfunk.jep.ParseException;
import org.nfunk.jep.function.PostfixMathCommand;


/**
 * 소수점이 있는걸 없게 변환하는 함수.
 * 입력 값은 byte[], 결과는 byte[]임.
 */
public class REMOVEPOINTS extends PostfixMathCommand {
    public REMOVEPOINTS() {
        numberOfParameters = 3;
    }

    public void run(Stack inStack) throws ParseException {
        checkStack(inStack);

        Object p3 = inStack.pop();

        if (p3 instanceof Number) {
            int _p3 = ((Number) p3).intValue();
            Object p2 = inStack.pop();

            if (p2 instanceof Number) {
                int _p2 = ((Number) p2).intValue();

                Object p1 = inStack.pop();

                if (p1 instanceof String) {
                    String str1 = (String) p1;
                    inStack.push(removePointSigned(str1,_p2,_p3));
                } else if (p1 instanceof byte[]) {
                    byte[] bytes = (byte[]) p1;
                    inStack.push(removePointSigned(new String(bytes),_p2,_p3));
                } else if (p1 instanceof BigDecimal) {
                    String str1  = ((BigDecimal) p1).toPlainString();
                    inStack.push(removePointSigned(str1,_p2,_p3));
                } else if (p1 instanceof Number) {
                	String str1  = ((Number) p1).toString();
                	inStack.push(removePointSigned(str1,_p2,_p3));
                } else {
                    throw new ParseException("Invalid parameter type, p1 is not string/bytes/double/number");
                }
            } else {
                throw new ParseException("Invalid parameter type, p2 is not number");
            }
        } else {
            throw new ParseException("Invalid parameter type, p3 is not number");
        }
    }
    
    public byte[] removePointSigned(String str , int plus , int minus) throws ParseException {
    	boolean isSigned = false;
    	
    	StringBuilder sb = new StringBuilder(plus+minus);
    	String nBody = null;
    	String dBody = null;
    	
    	if (str == null || str.trim().length() ==0 ){
    		return StringUtils.leftPad("0",plus+minus,"0").getBytes();
    	}
    	else {
    		str = str.trim();
    	}
    	
    	String signBit = str.substring(0,1);
    	if(signBit.equals("+") || signBit.equals("-")) {
    		isSigned = true;
    		str = str.substring(1);
    	}
    	else {
    		isSigned = false;
    		signBit = "+";
    	}
    	
    	// 부호도 길이에 포함됨
    	plus = plus -1;
    	
    	int pointPos = str.indexOf(".");
    	if (pointPos<0){
    		if(str.length() > plus) {
        		throw new ParseException("data size overflow integer part >"+plus+", data="+ str);
        	}
        }
    	else {
    		if(pointPos > plus) {
        		throw new ParseException("data size overflow integer part > "+plus +", data="+ str);
        	}
    		
    		if((str.length() - pointPos - 1) > minus) {
//    			System.out.println(str.length());
//    			System.out.println(pointPos);
        		throw new ParseException("data size overflow decimal part > "+minus +", data="+ str);
        	}
        }
    	
    	if (pointPos<0){
        	nBody = str;
        	dBody = "";
        }
    	else {
    		nBody = str.substring(0,pointPos);
        	dBody = str.substring(pointPos+1);
        }
    	
    	nBody = StringUtils.leftPad(nBody, plus, "0");
    	dBody = StringUtils.rightPad(dBody, minus, "0");
    	
    	sb.append(signBit);
    	sb.append(nBody);
    	sb.append(dBody);
    	
    	return sb.toString().getBytes();
    }
    public static void main(String[] args) throws Exception{
    	REMOVEPOINTS point = new REMOVEPOINTS();
    	
    	// System.out.println(new String(point.addStack(new String("-1.2"), 6, 2)));
    	// System.out.println(new String(point.addStack(new String("-1.2"), 6, 0)));
    	// System.out.println(new String(point.addStack(new String("-1.2"), 12, 2)));
    	// System.out.println(new String(point.addStack(new BigDecimal("-1000000000000000000.2"), 20, 2)));
    	// System.out.println(new String(point.addStack(new Double("-1000000000000000000.2"), 20, 2)));
    	
    }
    /**
     * 내부 테스트용 
     * @param o
     * @param n
     * @param f
     * @return
     */
    protected byte[] addStack(Object o, int n, int f){
    	Stack inStack = new Stack();
    	
    	inStack.add(o);
    	inStack.add(n);
    	inStack.add(f);
		try {
			run(inStack);
		} catch (ParseException e) {
			
			e.printStackTrace();
			return new byte[0];
		}
    	return (byte[])inStack.pop();
    }
}
