package alien4cloud.utils.services;

import alien4cloud.exception.InvalidArgumentException;
import org.alien4cloud.tosca.model.definitions.PropertyDefinition;
import alien4cloud.paas.exception.NotSupportedException;
import org.alien4cloud.tosca.normative.types.IPropertyType;
import org.alien4cloud.tosca.exceptions.InvalidPropertyValueException;
import org.alien4cloud.tosca.normative.types.ScalarType;
import org.alien4cloud.tosca.normative.primitives.ScalarUnit;
import org.alien4cloud.tosca.normative.types.ToscaTypes;
import alien4cloud.utils.MapUtil;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PropertyValueService {

    /**
     * Extract the value from a sub-path of a property.
     * 
     * @param propertyValue The value of the property.
     * @param path The path to get the value.
     * @return The value at the given path or propertyValue if the path is null or empty.
     */
    public static Object getValue(Object propertyValue, String path) {
        if (path == null || path.isEmpty()) {
            return propertyValue;
        }
        return MapUtil.get(propertyValue, path);
    }

    /**
     * Get a property value in the given unit.
     *
     * @param propertyValue The property value from which to get the value in a specified unit
     * @param unit The unit in which to get the value.
     * @param propertyDefinition The property definition of the root property.
     * @return The value in the correct unit.
     */
    public static String getValueInUnit(Object propertyValue, String unit, boolean ceil, PropertyDefinition propertyDefinition) {
        // TODO manage complex objects and sub-paths
        // @param path The optional sub-path of the property (may be null or empty).
        if (propertyValue instanceof String) {
            return getValueInUnit((String) propertyValue, unit, ceil, propertyDefinition.getType());
        } else if (propertyValue instanceof List) {
            log.error("Conversion of unit is currently not supported for complex properties");
            throw new NotSupportedException("Conversion of unit is currently not supported for complex properties");
        } else if (propertyValue instanceof Map) {
            log.error("Conversion of unit is currently not supported for complex properties");
            throw new NotSupportedException("Conversion of unit is currently not supported for complex properties");
        } else {
            throw new InvalidArgumentException(
                    "Not expecting to receive unit conversion for other types than String, Map or List as " + propertyValue.getClass().getName());
        }
    }

    private static String getValueInUnit(String propertyValue, String unit, boolean ceil, String toscaType) {
        IPropertyType type = ToscaTypes.fromYamlTypeName(toscaType);
        if (type instanceof ScalarType) {
            try {
                ScalarUnit scalarUnit = ((ScalarType) type).parse(propertyValue);
                double convertedValue = scalarUnit.convert(unit);
                if (ceil) {
                    convertedValue = Math.ceil(convertedValue);
                }
                return format(convertedValue);
            } catch (InvalidPropertyValueException e) {
                log.error("e");
                throw new InvalidArgumentException(e.getMessage());
            }
        }
        throw new InvalidArgumentException("Type is not a scalar type");
    }

    private static String format(double d) {
        if (d == (long) d)
            return String.format("%d", (long) d);
        else
            return String.format("%s", d);
    }
}
@@ -2676,38 +2676,37 @@
   %7D%0A    %7D%0A%0A    p
-rivate
+ublic
  static String g

Allow to get property value with units without having the property definition.