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

#pragma once

#include <glog/logging.h>
#include <stdint.h>

// IWYU pragma: no_include <bits/std_abs.h>
#include <cmath> // IWYU pragma: keep
#include <cstdlib>
#include <iostream>
#include <string>
#include <string_view>

#include "util/hash_util.hpp"
#include "vec/core/wide_integer.h"

namespace doris {

typedef __int128_t int128_t;

enum DecimalError {
    E_DEC_OK = 0,
    E_DEC_TRUNCATED = 1,
    E_DEC_OVERFLOW = 2,
    E_DEC_DIV_ZERO = 4,
    E_DEC_BAD_NUM = 8,
    E_DEC_OOM = 16,

    E_DEC_ERROR = 31,
    E_DEC_FATAL_ERROR = 30
};

enum DecimalRoundMode { HALF_UP = 1, HALF_EVEN = 2, CEILING = 3, FLOOR = 4, TRUNCATE = 5 };

class DecimalV2Value {
public:
    using NativeType = __int128_t;
    friend DecimalV2Value operator+(const DecimalV2Value& v1, const DecimalV2Value& v2);
    friend DecimalV2Value operator-(const DecimalV2Value& v1, const DecimalV2Value& v2);
    friend DecimalV2Value operator*(const DecimalV2Value& v1, const DecimalV2Value& v2);
    friend DecimalV2Value operator/(const DecimalV2Value& v1, const DecimalV2Value& v2);
    friend std::istream& operator>>(std::istream& ism, DecimalV2Value& decimal_value);
    friend DecimalV2Value operator-(const DecimalV2Value& v);

    static constexpr int32_t PRECISION = 27;
    static constexpr int32_t SCALE = 9;
    static constexpr int32_t SCALE_TRIM_ARRAY[SCALE + 1] = {
            1000000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
    static constexpr uint32_t ONE_BILLION = 1000000000;
    static constexpr int64_t MAX_INT_VALUE = 999999999999999999;
    static constexpr int32_t MAX_FRAC_VALUE = 999999999;
    static constexpr int64_t MAX_INT64 = 9223372036854775807ll;
    // In sqrt, the integer part and the decimal part of the square root to be solved separately are
    // multiplied by the PRECISION/2 power of 10, so that they can be placed in an int128_t variable
    static const int128_t SQRT_MOLECULAR_MAGNIFICATION;
    // sqrt(ONE_BILLION) * pow(10, PRECISION/2 - SCALE), it is used to calculate SCALE of the sqrt result
    static const int128_t SQRT_DENOMINATOR;

    static const int128_t MAX_DECIMAL_VALUE =
            static_cast<int128_t>(MAX_INT64) * ONE_BILLION + MAX_FRAC_VALUE;

    DecimalV2Value() = default;
    const int128_t& value() const { return _value; }
    int128_t& value() { return _value; }

    DecimalV2Value(const std::string& decimal_str) {
        parse_from_str(decimal_str.c_str(), decimal_str.size());
    }

    DecimalV2Value(const std::string_view& decimal_str) {
        parse_from_str(decimal_str.data(), decimal_str.size());
    }
    // Construct from olap engine
    DecimalV2Value(int64_t int_value, int64_t frac_value) {
        from_olap_decimal(int_value, frac_value);
    }

    bool from_olap_decimal(int64_t int_value, int64_t frac_value) {
        bool success = true;
        bool is_negative = (int_value < 0 || frac_value < 0);
        if (is_negative) {
            int_value = std::abs(int_value);
            frac_value = std::abs(frac_value);
        }

        //if (int_value > MAX_INT_VALUE) {
        //    int_value = MAX_INT_VALUE;
        //    success = false;
        //}

        if (frac_value > MAX_FRAC_VALUE) {
            frac_value = MAX_FRAC_VALUE;
            success = false;
        }

        _value = static_cast<int128_t>(int_value) * ONE_BILLION + frac_value;
        if (is_negative) _value = -_value;

        return success;
    }

    explicit DecimalV2Value(int128_t int_value) { _value = int_value; }

    void set_value(int128_t value) { _value = value; }

    DecimalV2Value& assign_from_float(const float float_value) {
        _value = static_cast<int128_t>(float_value * ONE_BILLION);
        return *this;
    }

    DecimalV2Value& assign_from_double(const double double_value) {
        _value = static_cast<int128_t>(double_value * ONE_BILLION);
        return *this;
    }

    // These cast functions are needed in "functions.cc", which is generated by python script.
    // e.g. "ComputeFunctions::Cast_DecimalV2Value_double()"
    // Discard the scale part
    // ATTN: invoker must make sure no OVERFLOW
    operator int64_t() const { return static_cast<int64_t>(_value / ONE_BILLION); }

    // These cast functions are needed in "functions.cc", which is generated by python script.
    // e.g. "ComputeFunctions::Cast_DecimalV2Value_double()"
    // Discard the scale part
    // ATTN: invoker must make sure no OVERFLOW
    operator int128_t() const { return static_cast<int128_t>(_value / ONE_BILLION); }

    operator wide::Int256() const {
        wide::Int256 result;
        wide::Int256::_impl::wide_integer_from_builtin(result, _value);
        return result;
    }

    operator bool() const { return _value != 0; }

    operator int8_t() const { return static_cast<char>(operator int64_t()); }

    operator int16_t() const { return static_cast<int16_t>(operator int64_t()); }

    operator int32_t() const { return static_cast<int32_t>(operator int64_t()); }

    operator size_t() const { return static_cast<size_t>(operator int64_t()); }

    operator float() const { return (float)operator double(); }

    operator double() const {
        std::string str_buff = to_string();
        double result = std::strtod(str_buff.c_str(), nullptr);
        return result;
    }

    DecimalV2Value& operator+=(const DecimalV2Value& other);

    // To be Compatible with OLAP
    // ATTN: NO-OVERFLOW should be guaranteed.
    int64_t int_value() const { return operator int64_t(); }

    // To be Compatible with OLAP
    // NOTE: return a negative value if decimal is negative.
    // ATTN: the max length of fraction part in OLAP is 9, so the 'big digits' except the first one
    // will be truncated.
    int32_t frac_value() const { return static_cast<int64_t>(_value % ONE_BILLION); }

    bool operator==(const DecimalV2Value& other) const { return _value == other.value(); }

    auto operator<=>(const DecimalV2Value& other) const { return _value <=> other.value(); }

    // change to maximum value for given precision and scale
    // precision/scale - see decimal_bin_size() below
    // to              - decimal where where the result will be stored
    void to_max_decimal(int precision, int frac);
    void to_min_decimal(int precision, int frac) {
        to_max_decimal(precision, frac);
        if (_value > 0) _value = -_value;
    }

    // The maximum of fraction part is "scale".
    // If the length of fraction part is less than "scale", '0' will be filled.
    std::string to_string(int scale) const;

    int32_t to_buffer(char* buffer, int scale) const;

    // Output actual "scale", remove ending zeroes.
    std::string to_string() const;

    // Convert string to decimal
    // @param from - value to convert. Doesn't have to be \0 terminated!
    //               will stop at the fist non-digit char(nor '.' 'e' 'E'),
    //               or reaches the length
    // @param length - maximum length
    // @return error number.
    //
    // E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW/E_DEC_BAD_NUM/E_DEC_OOM
    // In case of E_DEC_FATAL_ERROR *to is set to decimal zero
    // (to make error handling easier)
    //
    // e.g. "1.2"  ".2"  "1.2e-3"  "1.2e3"
    int parse_from_str(const char* decimal_str, int32_t length);

    std::string get_debug_info() const { return to_string(); }

    static DecimalV2Value get_min_decimal() {
        return DecimalV2Value(-MAX_INT_VALUE, MAX_FRAC_VALUE);
    }

    static DecimalV2Value get_max_decimal() {
        return DecimalV2Value(MAX_INT_VALUE, MAX_FRAC_VALUE);
    }

    static DecimalV2Value get_min_decimal(int precision, int scale) {
        DCHECK(precision <= 27 && scale <= 9);
        return DecimalV2Value(
                -MAX_INT_VALUE % get_scale_base(18 - precision + scale),
                MAX_FRAC_VALUE / get_scale_base(9 - scale) * get_scale_base(9 - scale));
    }

    static DecimalV2Value get_max_decimal(int precision, int scale) {
        DCHECK(precision <= 27 && scale <= 9);
        return DecimalV2Value(
                MAX_INT_VALUE % get_scale_base(18 - precision + scale),
                MAX_FRAC_VALUE / get_scale_base(9 - scale) * get_scale_base(9 - scale));
    }

    // Solve Square root for int128
    static DecimalV2Value sqrt(const DecimalV2Value& v);

    // set DecimalV2Value to zero
    void set_to_zero() { _value = 0; }

    void to_abs_value() {
        if (_value < 0) _value = -_value;
    }

    uint32_t hash(uint32_t seed) const { return HashUtil::hash(&_value, sizeof(_value), seed); }

    int32_t precision() const { return PRECISION; }

    int32_t scale() const { return SCALE; }

    bool greater_than_scale(int scale);

    int round(DecimalV2Value* to, int scale, DecimalRoundMode mode);

    inline static int128_t get_scale_base(int scale) {
        static const int128_t values[] = {
                static_cast<int128_t>(1ll),
                static_cast<int128_t>(10ll),
                static_cast<int128_t>(100ll),
                static_cast<int128_t>(1000ll),
                static_cast<int128_t>(10000ll),
                static_cast<int128_t>(100000ll),
                static_cast<int128_t>(1000000ll),
                static_cast<int128_t>(10000000ll),
                static_cast<int128_t>(100000000ll),
                static_cast<int128_t>(1000000000ll),
                static_cast<int128_t>(10000000000ll),
                static_cast<int128_t>(100000000000ll),
                static_cast<int128_t>(1000000000000ll),
                static_cast<int128_t>(10000000000000ll),
                static_cast<int128_t>(100000000000000ll),
                static_cast<int128_t>(1000000000000000ll),
                static_cast<int128_t>(10000000000000000ll),
                static_cast<int128_t>(100000000000000000ll),
                static_cast<int128_t>(1000000000000000000ll),
                static_cast<int128_t>(1000000000000000000ll) * 10ll,
                static_cast<int128_t>(1000000000000000000ll) * 100ll,
                static_cast<int128_t>(1000000000000000000ll) * 1000ll,
                static_cast<int128_t>(1000000000000000000ll) * 10000ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000ll,
                static_cast<int128_t>(1000000000000000000ll) * 1000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 10000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 1000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 10000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 1000000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 10000000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 1000000000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 10000000000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 10ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 100ll,
                static_cast<int128_t>(1000000000000000000ll) * 100000000000000000ll * 1000ll};
        if (scale >= 0 && scale < 38) return values[scale];
        return -1; // Overflow
    }

    bool is_zero() const { return _value == 0; }

private:
    int128_t _value;
};

DecimalV2Value operator+(const DecimalV2Value& v1, const DecimalV2Value& v2);
DecimalV2Value operator-(const DecimalV2Value& v1, const DecimalV2Value& v2);
DecimalV2Value operator*(const DecimalV2Value& v1, const DecimalV2Value& v2);
DecimalV2Value operator/(const DecimalV2Value& v1, const DecimalV2Value& v2);
DecimalV2Value operator%(const DecimalV2Value& v1, const DecimalV2Value& v2);

DecimalV2Value operator-(const DecimalV2Value& v);

std::ostream& operator<<(std::ostream& os, DecimalV2Value const& decimal_value);
std::istream& operator>>(std::istream& ism, DecimalV2Value& decimal_value);

std::size_t hash_value(DecimalV2Value const& value);

} // end namespace doris

template <>
struct std::hash<doris::DecimalV2Value> {
    size_t operator()(const doris::DecimalV2Value& v) const { return doris::hash_value(v); }
};

template <>
struct std::equal_to<doris::DecimalV2Value> {
    bool operator()(const doris::DecimalV2Value& lhs, const doris::DecimalV2Value& rhs) const {
        return lhs == rhs;
    }
};