// 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.


#ifndef IMPALA_RUNTIME_DECIMAL_VALUE_H
#define IMPALA_RUNTIME_DECIMAL_VALUE_H

#include <ostream>

#include "gen-cpp/Data_types.h"
#include "runtime/multi-precision.h"
#include "runtime/types.h"

#ifndef __has_builtin
#define __has_builtin(x) 0
#endif

namespace impala {

/// Implementation of decimal types. The type is parametrized on the underlying
/// storage type, which must implement all operators (example of a storage type
/// is int32_t). The decimal does not store its precision and scale since we'd
/// like to keep the storage as small as possible.
/// Overflow handling: anytime the value is assigned, we need to consider overflow.
/// Overflow is handled by an output return parameter. Functions should set this
/// to true if overflow occured and leave it *unchanged* otherwise (e.g. |= rather than =).
/// This allows the caller to not have to check overflow after every call.
template<typename T>
class DecimalValue {
 public:
  typedef T StorageType;

  DecimalValue() : value_(0) { }
  DecimalValue(const T& s) : value_(s) { }

  DecimalValue& operator=(const T& s) {
    value_ = s;
    return *this;
  }

  /// Returns the closest Decimal to 'd' of type 't', rounding to the nearest integer
  /// if 'round' is true, truncating the decimal places otherwise
  static inline DecimalValue FromDouble(const ColumnType& t, double d, bool round,
      bool* overflow) {
    return FromDouble(t.precision, t.scale, d, round, overflow);
  }

  /// Returns a new DecimalValue created from the value in 'tvalue'.
  static inline DecimalValue FromTColumnValue(const TColumnValue& tvalue);

  static inline DecimalValue FromDouble(int precision, int scale, double d,
      bool round, bool* overflow);

  /// Assigns *result as a decimal.
  static inline DecimalValue FromInt(int precision, int scale, int64_t d, bool* overflow);

  /// The overloaded operators assume that this and other have the same scale. They are
  /// more efficient than the comparison functions that handle differing scale and should
  /// be used if the scales are known to be the same.  (e.g. min(decimal_col) or order by
  /// decimal_col.
  bool operator==(const DecimalValue& other) const {
    return value_ == other.value_;
  }
  bool operator!=(const DecimalValue& other) const {
    return value_ != other.value_;
  }
  bool operator<=(const DecimalValue& other) const {
    return value_ <= other.value_;
  }
  bool operator<(const DecimalValue& other) const {
    return value_ < other.value_;
  }
  bool operator>=(const DecimalValue& other) const {
    return value_ >= other.value_;
  }
  bool operator>(const DecimalValue& other) const {
    return value_ > other.value_;
  }

  DecimalValue operator-() const {
    return DecimalValue(-value_);
  }

  bool is_negative() const { return value_ < 0; }

  /// Compares this and other. Returns 0 if equal, < 0 if this < other and > 0 if
  /// this > other.
  inline int Compare(const DecimalValue& other) const;

  /// Returns a new decimal scaled by from src_type to dst_type.
  /// e.g. If this value was 1100 at scale 3 and the dst_type had scale two, the
  /// result would be 110. (In both cases representing the decimal 1.1).
  inline DecimalValue ScaleTo(int src_scale, int dst_scale, int dst_precision,
      bool* overflow) const;

  /// Implementations of the basic arithmetic operators. In all these functions,
  /// we take the precision and scale of both inputs. The return type is assumed
  /// to be known by the caller (generated by the planner).
  /// Although these functions accept the result scale, that should be seen as
  /// an optimization to avoid having to recompute it in the function. The
  /// functions implement the SQL decimal rules *only* so other result scales are
  /// not valid.
  /// RESULT_T needs to be larger than T to avoid overflow issues.
  template<typename RESULT_T>
  inline DecimalValue<RESULT_T> Add(int this_scale, const DecimalValue& other,
      int other_scale, int result_precision, int result_scale, bool round,
      bool* overflow) const;

  template<typename RESULT_T>
  inline DecimalValue<RESULT_T> Subtract(int this_scale, const DecimalValue& other,
      int other_scale, int result_precision, int result_scale, bool round,
      bool* overflow) const {
    return Add<RESULT_T>(this_scale, -other, other_scale, result_precision,
        result_scale, round, overflow);
  }

  template<typename RESULT_T>
  inline DecimalValue<RESULT_T> Multiply(int this_scale, const DecimalValue& other,
      int other_scale, int result_precision, int result_scale, bool round,
      bool* overflow) const;

  /// is_nan is set to true if 'other' is 0. The value returned is undefined.
  template<typename RESULT_T>
  inline DecimalValue<RESULT_T> Divide(int this_scale, const DecimalValue& other,
      int other_scale, int result_precision, int result_scale, bool round,
      bool* is_nan, bool* overflow) const;

  template<typename RESULT_T>
  inline DecimalValue<RESULT_T> Mod(int this_scale, const DecimalValue& other,
      int other_scale, int result_precision, int result_scale, bool round,
      bool* is_nan, bool* overflow) const;

  /// Compares this and other. Returns 0 if equal, < 0 if this < other and > 0 if
  /// this > other.
  inline int Compare(int this_scale, const DecimalValue& other, int other_scale) const;

  /// Comparison utilities.
  inline bool Eq(int this_scale, const DecimalValue& other, int other_scale) const {
    return Compare(this_scale, other, other_scale) == 0;
  }
  inline bool Ne(int this_scale, const DecimalValue& other, int other_scale) const {
    return Compare(this_scale, other, other_scale) != 0;
  }
  inline bool Ge(int this_scale, const DecimalValue& other, int other_scale) const {
    return Compare(this_scale, other, other_scale) >= 0;
  }
  inline bool Gt(int this_scale, const DecimalValue& other, int other_scale) const {
    return Compare(this_scale, other, other_scale) > 0;
  }
  inline bool Le(int this_scale, const DecimalValue& other, int other_scale) const {
    return Compare(this_scale, other, other_scale) <= 0;
  }
  inline bool Lt(int this_scale, const DecimalValue& other, int other_scale) const {
    return Compare(this_scale, other, other_scale) < 0;
  }

  /// Returns the underlying storage. For a particular storage size, there is
  /// only one representation for any decimal and the storage is directly comparable.
  inline const T& value() const { return value_; }
  inline T& value() { return value_; }

  /// Returns the value of the decimal before the decimal point.
  inline const T whole_part(int scale) const;

  /// Returns the value of the decimal after the decimal point.
  inline const T fractional_part(int scale) const;

  /// Returns the value as an integer, setting overflow to true on overflow,
  /// and leaving unchanged otherwise.  Rounds to the nearest integer, defined
  /// as half / round away from zero.  Template parameter RESULT_T should be a
  /// UDF Val type which defines an integer underlying type as underlying_type_t
  template <typename RESULT_T>
  inline typename RESULT_T::underlying_type_t ToInt(int scale, bool* overflow) const;

  /// Returns an approximate double for this decimal.
  inline double ToDouble(int scale) const;

  inline uint32_t Hash(int seed = 0) const;

  std::string ToString(const ColumnType& type) const;
  std::string ToString(int precision, int scale) const;

  inline DecimalValue<T> Abs() const;

  /// Store the binary representation of this DecimalValue in 'tvalue'.
  void ToTColumnValue(TColumnValue* tvalue) const {
    const uint8_t* data = reinterpret_cast<const uint8_t*>(&value_);
    tvalue->decimal_val.assign(data, data + sizeof(T));
    tvalue->__isset.decimal_val = true;
  }

 private:
  T value_;

  /// Returns in *x_val and *y_val, the adjusted values so that both are at
  /// max(x_scale, y_scale) scale. It is the job of the caller to make sure
  /// that both numbers can fit into RESULT_T after being scaled up.
  template <typename RESULT_T>
  static inline void AdjustToSameScale(const DecimalValue& x, int x_scale,
      const DecimalValue& y, int y_scale, int result_precision, RESULT_T* x_scaled,
      RESULT_T* y_scaled);
};

typedef DecimalValue<int32_t> Decimal4Value;
typedef DecimalValue<int64_t> Decimal8Value;
/// TODO: should we support Decimal12Value? We pad it to 16 bytes in the tuple
/// anyway.
typedef DecimalValue<int128_t> Decimal16Value;

inline std::ostream& operator<<(std::ostream& os, const Decimal4Value& d) {
  return os << d.value();
}
inline std::ostream& operator<<(std::ostream& os, const Decimal8Value& d) {
  return os << d.value();
}
inline std::ostream& operator<<(std::ostream& os, const Decimal16Value& d) {
  return os << d.value();
}

}

#endif
