// 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 "util/string_parser.hpp"

#include <limits>

#include "core/extended_types.h"
#include "core/types.h"
namespace doris {
#include "common/compile_check_avoid_begin.h"
// Supported decimal number format:
// <decimal> ::= <whitespace>* <value> <whitespace>*
//
// <whitespace> ::= " " | "\t" | "\n" | "\r" | "\f" | "\v"
//
// <value> ::= <sign>? <significand> <exponent>?
//
// <sign> ::= "+" | "-"
//
// <significand> ::= <digits> "." <digits> | <digits> | <digits> "." | "." <digits>
//
// <digits> ::= <digit>+
//
// <digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
//
// <exponent> ::= <e_marker> <sign>? <digits>
//
// <e_marker> ::= "e" | "E"
//
// Parsing algorithm:
// 1. Trim spaces and the sign, then normalize the significand by skipping leading zeros and an
//    optional leading dot. During this scan, count digits that belong to the original integral
//    part (`int_part_count`) and remember where the significand ends (`end_digit_index`).
// 2. Parse the optional exponent. Scientific notation is handled by moving the decimal point:
//    `result_int_part_digit_count = int_part_count + exponent`. For example, "12.34e-1" has
//    int_part_count=2 and exponent=-1, so the result has one integral digit: "1.234".
// 3. Build the result in scaled-integer form: first collect the integral digits up to the shifted
//    decimal point, then collect up to `type_scale` fractional digits, padding with zeros when the
//    input has fewer fractional digits than the target scale.
// 4. If there are extra fractional digits, round half up using the first discarded digit. Finally,
//    check the integral digit count against `type_precision - type_scale` and return the signed
//    scaled integer value.
template <PrimitiveType P>
typename PrimitiveTypeTraits<P>::CppType::NativeType StringParser::string_to_decimal(
        const char* __restrict s, size_t len, int type_precision, int type_scale,
        ParseResult* result) {
    using T = typename PrimitiveTypeTraits<P>::CppType::NativeType;
    static_assert(std::is_same_v<T, int32_t> || std::is_same_v<T, int64_t> ||
                          std::is_same_v<T, __int128> || std::is_same_v<T, wide::Int256>,
                  "Cast string to decimal only support target type int32_t, int64_t, __int128 or "
                  "wide::Int256.");

    // Parse in two logical coordinate systems:
    // 1. `s[0, end_digit_index)` is the normalized significand after trimming spaces, sign and
    //    leading zeros. If the original value starts with '.', the dot is also skipped so
    //    ".14E+3" is parsed as significand "14" with exponent 3.
    // 2. `result_int_part_digit_count = int_part_count + exponent` is the decimal point position
    //    after applying scientific notation. For example, "1.4E+2" has int_part_count=1,
    //    exponent=2, result_int_part_digit_count=3, so "14" becomes integer 140.
    // `digit_index` always indexes the normalized significand string, which may still contain a
    // dot for inputs like "1.4E+2"; loops that build numbers skip that dot explicitly.
    // Ignore leading and trailing spaces.
    s = skip_ascii_whitespaces(s, len);

    bool is_negative = false;
    if (len > 0) {
        switch (*s) {
        case '-':
            is_negative = true;
            [[fallthrough]];
        case '+':
            ++s;
            --len;
        }
    }
    // Ignore leading zeros.
    bool found_value = false;
    while (len > 0 && UNLIKELY(*s == '0')) {
        found_value = true;
        ++s;
        --len;
    }

    int found_dot = 0;
    if (len > 0 && *s == '.') {
        found_dot = 1;
        ++s;
        --len;
    }
    int int_part_count = 0;
    int i = 0;
    for (; i != len; ++i) {
        const char& c = s[i];
        if (LIKELY('0' <= c && c <= '9')) {
            found_value = true;
            if (!found_dot) {
                ++int_part_count;
            }
        } else if (c == '.') {
            if (found_dot) {
                *result = StringParser::PARSE_FAILURE;
                return 0;
            }
            found_dot = 1;
        } else {
            break;
        }
    }
    if (!found_value) {
        // '', '.'
        *result = StringParser::PARSE_FAILURE;
        return 0;
    }
    // Parse exponent if any. Keep `end_digit_index` before consuming 'e/E' so later digit counts
    // ignore exponent syntax. For "1.4E+2", end_digit_index points just after "1.4", not after
    // "E+2".
    int64_t exponent = 0;
    auto end_digit_index = i;
    if (i != len) {
        bool negative_exponent = false;
        if (s[i] == 'e' || s[i] == 'E') {
            ++i;
            if (i != len) {
                switch (s[i]) {
                case '-':
                    negative_exponent = true;
                    [[fallthrough]];
                case '+':
                    ++i;
                }
            }
            if (i == len) {
                // '123e', '123e+', '123e-'
                *result = StringParser::PARSE_FAILURE;
                return 0;
            }
            for (; i != len; ++i) {
                const char& c = s[i];
                if (LIKELY('0' <= c && c <= '9')) {
                    exponent = exponent * 10 + (c - '0');
                    // max string len is config::string_type_length_soft_limit_bytes,
                    // whose max value is std::numeric_limits<int32_t>::max() - 4,
                    // just check overflow of int32_t to simplify the logic
                    // For edge cases like 0.{2147483647 zeros}e+2147483647
                    if (exponent > std::numeric_limits<int32_t>::max()) {
                        *result = StringParser::PARSE_OVERFLOW;
                        return 0;
                    }
                } else {
                    // '123e12abc', '123e1.2'
                    *result = StringParser::PARSE_FAILURE;
                    return 0;
                }
            }
            if (negative_exponent) {
                exponent = -exponent;
            }
        } else {
            *result = StringParser::PARSE_FAILURE;
            return 0;
        }
    }
    // TODO: check limit values of exponent and add UT
    // max string len is config::string_type_length_soft_limit_bytes,
    // whose max value is std::numeric_limits<int32_t>::max() - 4,
    // so int_part_count will be in range of int32_t,
    // and int_part_count + exponent will be in range of int64_t
    int64_t tmp_result_int_part_digit_count = int_part_count + exponent;
    if (tmp_result_int_part_digit_count > std::numeric_limits<int>::max() ||
        tmp_result_int_part_digit_count < std::numeric_limits<int>::min()) {
        *result = is_negative ? StringParser::PARSE_UNDERFLOW : StringParser::PARSE_OVERFLOW;
        return 0;
    }
    int result_int_part_digit_count = tmp_result_int_part_digit_count;
    T int_part_number = 0;
    T frac_part_number = 0;
    int actual_frac_part_count = 0;
    int digit_index = 0;
    if (result_int_part_digit_count >= 0) {
        // `max_index` is the raw significand index where integer-part digits stop. Add one extra
        // raw character only when crossing an in-buffer dot, e.g. "1.4E+2" must scan "1.4" to
        // collect three integer digits after the exponent shift. It is capped by end_digit_index
        // because missing digits are appended later by multiplying with powers of 10.
        int max_index = std::min(found_dot ? (result_int_part_digit_count +
                                              ((int_part_count > 0 && exponent > 0) ? 1 : 0))
                                           : result_int_part_digit_count,
                                 end_digit_index);
        max_index = (max_index == std::numeric_limits<int>::min() ? end_digit_index : max_index);
        // skip zero number
        for (; digit_index != max_index && s[digit_index] == '0'; ++digit_index) {
        }
        // test 0.00, .00, 0.{00...}e2147483647
        // 0.00000e2147483647
        if (digit_index != max_index &&
            (result_int_part_digit_count - digit_index > type_precision - type_scale)) {
            *result = is_negative ? StringParser::PARSE_UNDERFLOW : StringParser::PARSE_OVERFLOW;
            return 0;
        }
        // get int part number
        for (; digit_index != max_index; ++digit_index) {
            if (UNLIKELY(s[digit_index] == '.')) {
                continue;
            }
            int_part_number = int_part_number * 10 + (s[digit_index] - '0');
        }
        // Count only significand digits, not exponent syntax. If the exponent moves the decimal
        // point past all available significant digits, append zeros by scaling the integer part:
        // "1.4E+2" scans integer 14, total_significant_digit_count=2, then multiplies by 10.
        auto total_significant_digit_count =
                end_digit_index - ((found_dot && int_part_count > 0) ? 1 : 0);
        if (result_int_part_digit_count > total_significant_digit_count) {
            int_part_number *= get_scale_multiplier<T>(result_int_part_digit_count -
                                                       total_significant_digit_count);
        }
    } else {
        // leading zeros of fraction part
        actual_frac_part_count = -result_int_part_digit_count;
    }
    // get fraction part number
    for (; digit_index != end_digit_index && actual_frac_part_count < type_scale; ++digit_index) {
        if (UNLIKELY(s[digit_index] == '.')) {
            continue;
        }
        frac_part_number = frac_part_number * 10 + (s[digit_index] - '0');
        ++actual_frac_part_count;
    }
    auto type_scale_multiplier = get_scale_multiplier<T>(type_scale);
    // Round only when the next parsed significand digit is exactly the first discarded fractional
    // digit. If `actual_frac_part_count` is already greater than type_scale, the missing positions
    // are implicit zeros from a negative exponent, so "5e-17" to scale 15 must stay 0 instead of
    // rounding up.
    if (actual_frac_part_count == type_scale && digit_index != end_digit_index) {
        if (UNLIKELY(s[digit_index] == '.')) {
            ++digit_index;
        }
        if (digit_index != end_digit_index) {
            // example: test 1.5 -> decimal(1, 0)
            if (s[digit_index] >= '5') {
                ++frac_part_number;
                if (frac_part_number == type_scale_multiplier) {
                    frac_part_number = 0;
                    ++int_part_number;
                }
            }
        }
    } else {
        if (actual_frac_part_count < type_scale) {
            frac_part_number *= get_scale_multiplier<T>(type_scale - actual_frac_part_count);
        }
    }
    if (int_part_number >= get_scale_multiplier<T>(type_precision - type_scale)) {
        *result = is_negative ? StringParser::PARSE_UNDERFLOW : StringParser::PARSE_OVERFLOW;
        return 0;
    }

    T value = int_part_number * type_scale_multiplier + frac_part_number;
    *result = StringParser::PARSE_SUCCESS;
    return is_negative ? T(-value) : T(value);
}

template Int32 StringParser::string_to_decimal<PrimitiveType::TYPE_DECIMAL32>(
        const char* __restrict s, size_t len, int type_precision, int type_scale,
        ParseResult* result);
template Int64 StringParser::string_to_decimal<PrimitiveType::TYPE_DECIMAL64>(
        const char* __restrict s, size_t len, int type_precision, int type_scale,
        ParseResult* result);
template Int128 StringParser::string_to_decimal<PrimitiveType::TYPE_DECIMAL128I>(
        const char* __restrict s, size_t len, int type_precision, int type_scale,
        ParseResult* result);
template Int128 StringParser::string_to_decimal<PrimitiveType::TYPE_DECIMALV2>(
        const char* __restrict s, size_t len, int type_precision, int type_scale,
        ParseResult* result);
template wide::Int256 StringParser::string_to_decimal<PrimitiveType::TYPE_DECIMAL256>(
        const char* __restrict s, size_t len, int type_precision, int type_scale,
        ParseResult* result);
} // end namespace doris
#include "common/compile_check_avoid_end.h"