package org.adridadou.ethereum.propeller.solidity.converters.encoders;

import org.adridadou.ethereum.propeller.exception.EthereumApiException;
import org.adridadou.ethereum.propeller.solidity.SolidityType;
import org.adridadou.ethereum.propeller.values.EthData;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Created by davidroon on 03.04.17.
 * This code is released under Apache 2 license
 */
public class NumberEncoder implements SolidityTypeEncoder {

    @Override
    public boolean canConvert(Class<?> type) {
        return type.getTypeName().equals("int") ||
                type.getTypeName().equals("long") ||
                type.getTypeName().equals("byte") ||
                Number.class.isAssignableFrom(type);
    }

    @Override
    public EthData encode(Object arg, SolidityType solidityType) {
        if (solidityType.name().startsWith("U")) {
            if (arg instanceof BigInteger) {
                //we can only accept non decimal values
                if (((BigInteger) arg).signum() == -1) {
                    throw new EthereumApiException("unsigned type cannot encode negative values");
                }
            } else if (arg instanceof BigDecimal) {
                return encode(((BigDecimal) arg).toBigInteger(), solidityType);
            } else if (((Number) arg).longValue() < 0) {
                throw new EthereumApiException("unsigned type cannot encode negative values." + ((Number) arg).longValue());
            }
        }
        if (arg instanceof BigInteger) {
            return EthData.of((BigInteger) arg);
        }
        return EthData.of(((Number) arg).longValue());
    }
}

@@ -546,16 +546,17 @@
  return 
+ 
 type.get
@@ -579,16 +579,23 @@
 s(%22int%22)
+       
  %7C%7C%0A    
@@ -639,16 +639,22 @@
 (%22long%22)
+      
  %7C%7C%0A    
@@ -698,16 +698,22 @@
 (%22byte%22)
+      
  %7C%7C%0A    
@@ -724,22 +724,381 @@
         
-Number
+type.getTypeName().equals(%22short%22)      %7C%7C%0A%0A                Integer.class.isAssignableFrom(type)    %7C%7C%0A                Long.class.isAssignableFrom(type)       %7C%7C%0A                Byte.class.isAssignableFrom(type)       %7C%7C%0A                Short.class.isAssignableFrom(type)      %7C%7C%0A                BigInteger.class.isAssignableFrom(type) %7C%7C%0A                BigDecimal
 .class.i
@@ -1308,64 +1308,8 @@
 ) %7B%0A
-                //we can only accept non decimal values%0A
     
@@ -1470,32 +1470,32 @@
               %7D%0A
-
             %7D el
@@ -1526,24 +1526,80 @@
 gDecimal) %7B%0A
+                //we can only accept non decimal values%0A
             

make NumberEncoder stricter to avoid sneaky bugs that are hard to debug