/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 ******************************************************************************/
package org.apache.olingo.odata2.core.edm;

import java.math.BigDecimal;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.olingo.odata2.api.edm.EdmFacets;
import org.apache.olingo.odata2.api.edm.EdmLiteralKind;
import org.apache.olingo.odata2.api.edm.EdmSimpleType;
import org.apache.olingo.odata2.api.edm.EdmSimpleTypeException;

/**
 * Implementation of the EDM simple type Double.
 * 
 */
public class EdmDouble extends AbstractSimpleType {

  // value-range limitations according to the CSDL document
  private static final int MAX_PRECISION = 15;
  private static final int MAX_SCALE = 308;

  private static final Pattern PATTERN = Pattern.compile(
      "(?:\\+|-)?\\p{Digit}+(?:\\.\\p{Digit}+)?(?:(?:E|e)(?:\\+|-)?\\p{Digit}{1,3})?(D|d)?");
  private static final EdmDouble instance = new EdmDouble();

  public static EdmDouble getInstance() {
    return instance;
  }

  @Override
  public boolean isCompatible(final EdmSimpleType simpleType) {
    return simpleType instanceof Bit
        || simpleType instanceof Uint7
        || simpleType instanceof EdmByte
        || simpleType instanceof EdmSByte
        || simpleType instanceof EdmInt16
        || simpleType instanceof EdmInt32
        || simpleType instanceof EdmInt64
        || simpleType instanceof EdmSingle
        || simpleType instanceof EdmDouble;
  }

  @Override
  public Class<?> getDefaultType() {
    return Double.class;
  }

  @Override
  protected <T> T internalValueOfString(final String value, final EdmLiteralKind literalKind, final EdmFacets facets,
      final Class<T> returnType) throws EdmSimpleTypeException {
    String valueString = value;
    Double result = null;
    // Handle special values first.
    if ("-INF".equals(value)) {
      result = Double.NEGATIVE_INFINITY;
    } else if ("INF".equals(value)) {
      result = Double.POSITIVE_INFINITY;
    } else if ("NaN".equals(value)) {
      result = Double.NaN;
    } else {
      // Now only "normal" numbers remain.
      final Matcher matcher = PATTERN.matcher(value);
      if (!matcher.matches()
          || (literalKind == EdmLiteralKind.URI) == (matcher.group(1) == null)) {
        throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
      }

      if (literalKind == EdmLiteralKind.URI) {
        valueString = value.substring(0, value.length() - 1);
      }

      // The number format is checked above, so we don't have to catch NumberFormatException.
      result = Double.valueOf(valueString);

      // "Real" infinite values have been treated already above, so we can throw an exception
      // if the conversion to a float results in an infinite value.
      if (result.isInfinite()) {
        throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_ILLEGAL_CONTENT.addContent(value));
      }
    }

    if (returnType.isAssignableFrom(Double.class)) {
      return returnType.cast(result);
    } else if (returnType.isAssignableFrom(Float.class)) {
      if (result.floatValue() == result) {
        return returnType.cast(result.floatValue());
      } else {
        throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value,
            returnType));
      }
    } else if (result.isInfinite() || result.isNaN()) {
      throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value,
          returnType));
    } else {
      try {
        final BigDecimal valueBigDecimal = new BigDecimal(valueString);
        if (returnType.isAssignableFrom(BigDecimal.class)) {
          return returnType.cast(valueBigDecimal);
        } else if (returnType.isAssignableFrom(Long.class)) {
          return returnType.cast(valueBigDecimal.longValueExact());
        } else if (returnType.isAssignableFrom(Integer.class)) {
          return returnType.cast(valueBigDecimal.intValueExact());
        } else if (returnType.isAssignableFrom(Short.class)) {
          return returnType.cast(valueBigDecimal.shortValueExact());
        } else if (returnType.isAssignableFrom(Byte.class)) {
          return returnType.cast(valueBigDecimal.byteValueExact());
        } else {
          throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(returnType));
        }

      } catch (final ArithmeticException e) {
        throw new EdmSimpleTypeException(EdmSimpleTypeException.LITERAL_UNCONVERTIBLE_TO_VALUE_TYPE.addContent(value,
            returnType), e);
      }
    }
  }

  @Override
  protected <T> String internalValueToString(final T value, final EdmLiteralKind literalKind, final EdmFacets facets)
      throws EdmSimpleTypeException {
    if (value instanceof Long) {
      if (Math.abs((Long) value) < Math.pow(10, MAX_PRECISION)) {
        return value.toString();
      } else {
        throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
      }
    } else if (value instanceof Integer || value instanceof Short || value instanceof Byte) {
      return value.toString();
    } else if (value instanceof Double) {
      final String result = value.toString();
      return ((Double) value).isInfinite() ? result.toUpperCase(Locale.ROOT)
          .substring(0, value.toString().length() - 5) : result;
    } else if (value instanceof Float) {
      final String result = value.toString();
      return ((Float) value).isInfinite() ? result.toUpperCase(Locale.ROOT).substring(0, value.toString().length() - 5)
          : result;
    } else if (value instanceof BigDecimal) {
      if (((BigDecimal) value).precision() <= MAX_PRECISION && Math.abs(((BigDecimal) value).scale()) <= MAX_SCALE) {
        return ((BigDecimal) value).toString();
      } else {
        throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_ILLEGAL_CONTENT.addContent(value));
      }
    } else {
      throw new EdmSimpleTypeException(EdmSimpleTypeException.VALUE_TYPE_NOT_SUPPORTED.addContent(value.getClass()));
    }
  }

  @Override
  public String toUriLiteral(final String literal) {
    return "-INF".equals(literal) || "INF".equals(literal) || "NaN".equals(literal) ?
        literal : literal + "D";
  }
}
