// 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 "gen-cpp/data_stream_service.pb.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 'value_pb'.
  static inline DecimalValue FromColumnValuePB(const ColumnValuePB& value_pb);

  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 'value_pb'.
  void ToColumnValuePB(ColumnValuePB* value_pb) const {
    const uint8_t* data = reinterpret_cast<const uint8_t*>(&value_);
    value_pb->mutable_decimal_val()->assign(data, data + sizeof(T));
  }

 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
