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

#include "paimon/common/utils/decimal_utils.h"

#include <algorithm>
#include <cctype>
#include <cstddef>
#include <utility>

#include "arrow/api.h"
#include "arrow/util/basic_decimal.h"
#include "arrow/util/decimal.h"
#include "fmt/format.h"
#include "paimon/common/utils/checked_cast.h"

namespace paimon {
Status DecimalUtils::CheckDecimalType(const arrow::DataType& type) {
    if (type.id() != arrow::Type::DECIMAL128) {
        return Status::Invalid(fmt::format("Invalid decimal type: {}", type.ToString()));
    }
    auto* decimal_type = checked_cast<const arrow::Decimal128Type*>(&type);
    if (decimal_type->precision() > Decimal::MAX_PRECISION ||
        decimal_type->precision() < Decimal::MIN_PRECISION) {
        return Status::Invalid(fmt::format("Invalid decimal type, precision must in range [{}, {}]",
                                           Decimal::MIN_PRECISION, Decimal::MAX_PRECISION));
    }
    if (decimal_type->precision() < decimal_type->scale()) {
        return Status::Invalid(fmt::format("Invalid decimal type {}, precision must >= scale",
                                           decimal_type->ToString()));
    }
    return Status::OK();
}

std::optional<arrow::Decimal128> DecimalUtils::RescaleDecimalWithOverflowCheck(
    const arrow::Decimal128& src_decimal, int32_t src_scale, int32_t target_precision,
    int32_t target_scale) {
    arrow::Decimal128 target_decimal = src_decimal;
    if (src_scale < target_scale) {
        int32_t delta_scale = target_scale - src_scale;
        arrow::BasicDecimal128 min_bound = arrow::BasicDecimal128::GetMinSentinel();
        arrow::BasicDecimal128 max_bound = arrow::BasicDecimal128::GetMaxSentinel();
        min_bound /= arrow::BasicDecimal128::GetScaleMultiplier(delta_scale);
        max_bound /= arrow::BasicDecimal128::GetScaleMultiplier(delta_scale);
        // scaled_decimal may be overflow 128 bits
        // noted that, arrow::Decimal.Rescale() is not safe
        if (src_decimal > max_bound || src_decimal < min_bound) {
            return std::nullopt;
        }
        target_decimal = src_decimal.IncreaseScaleBy(delta_scale);
    } else if (src_scale > target_scale) {
        target_decimal = src_decimal.ReduceScaleBy(src_scale - target_scale, /*round=*/true);
    }
    if (!target_decimal.FitsInPrecision(target_precision)) {
        return std::nullopt;
    }
    return target_decimal;
}

Result<Decimal::int128_t> DecimalUtils::StrToInt128(const std::string& str) {
    try {
        size_t length = str.length();
        if (length == 0) {
            return Status::Invalid("invalid string: [], cannot convert to int128");
        }
        bool is_negative = str[0] == '-';
        size_t posn = is_negative ? 1 : 0;
        if (posn == length) {
            return Status::Invalid(
                fmt::format("invalid string: [{}], cannot convert to int128", str));
        }

        Decimal::uint128_t magnitude = 0;
        Decimal::uint128_t max_magnitude = (static_cast<Decimal::uint128_t>(1) << 127) - 1;
        if (is_negative) {
            max_magnitude += 1;
        }
        while (posn < length) {
            size_t group = std::min(18ul, length - posn);
            for (size_t i = 0; i < group; ++i) {
                if (!std::isdigit(static_cast<unsigned char>(str[posn + i]))) {
                    return Status::Invalid(
                        fmt::format("invalid string: [{}], cannot convert to int128", str));
                }
            }
            uint64_t chunk = std::stoull(str.substr(posn, group));
            uint64_t multiple = 1;
            for (size_t i = 0; i < group; ++i) {
                multiple *= 10;
            }
            if (magnitude > (max_magnitude - chunk) / multiple) {
                return Status::Invalid(
                    fmt::format("invalid string: [{}], cannot convert to int128", str));
            }
            magnitude = magnitude * multiple + chunk;
            posn += group;
        }
        if (is_negative) {
            if (magnitude == max_magnitude) {
                auto max_value =
                    static_cast<Decimal::int128_t>((static_cast<Decimal::uint128_t>(1) << 127) - 1);
                return -max_value - 1;
            }
            return -static_cast<Decimal::int128_t>(magnitude);
        }
        return static_cast<Decimal::int128_t>(magnitude);
    } catch (...) {
        return Status::Invalid(fmt::format("invalid string: [{}], cannot convert to int128", str));
    }
}

}  // namespace paimon
