/*
 * 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 <cstddef>
#include <utility>

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

namespace paimon {
Status DecimalUtils::CheckDecimalType(const arrow::DataType& type) {
    auto* decimal_type = dynamic_cast<const arrow::Decimal128Type*>(&type);
    if (!decimal_type) {
        return Status::Invalid(fmt::format("Invalid decimal type: {}", type.ToString()));
    }
    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 {
        Decimal::int128_t ret = 0;
        size_t length = str.length();
        if (length > 0) {
            bool is_negative = str[0] == '-';
            size_t posn = is_negative ? 1 : 0;
            while (posn < length) {
                size_t group = std::min(18ul, length - posn);
                int64_t chunk = std::stoll(str.substr(posn, group));
                int64_t multiple = 1;
                for (size_t i = 0; i < group; ++i) {
                    multiple *= 10;
                }
                ret *= multiple;
                ret += chunk;
                posn += group;
            }
            if (is_negative) {
                ret = -ret;
            }
        }
        return ret;
    } catch (...) {
        return Status::Invalid(fmt::format("invalid string: [{}], cannot convert to int128", str));
    }
}

}  // namespace paimon
