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

"""Java decimal schema evolution: decimal text, HALF_UP, then precision."""

from decimal import Context, Decimal, InvalidOperation, localcontext, ROUND_HALF_UP
import re

import pyarrow as pa

from pypaimon.utils.numeric_utils import java_double_decimal_text


_DECIMAL_TEXT = re.compile(r'[+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?\Z')


def cast_decimal(array, target):
    """Return None for conversions outside the existing decimal read support.

    FLOAT values from Arrow are already widened to Python double. Java does
    the same widening before BigDecimal.valueOf, retaining the float's binary
    rounding. A valid decimal overflowing the target is NULL; invalid text
    fails the conversion instead of silently becoming NULL.
    """
    floating = pa.types.is_floating(array.type)
    integer = pa.types.is_signed_integer(array.type)
    text = pa.types.is_string(array.type)
    if not pa.types.is_decimal(target) or not (integer or floating or text or pa.types.is_decimal(array.type)):
        return None
    values = []
    # The caller's rounding traps and exponent limits must not affect reads.
    # One extra digit allows rounding to carry, before the precision check.
    context = Context(prec=target.precision + 1, rounding=ROUND_HALF_UP,
                      Emin=-999999, Emax=999999, clamp=0, traps=[InvalidOperation])
    with localcontext(context):
        quantum = Decimal(1).scaleb(-target.scale)
        for value in array.to_pylist():
            if value is None:
                values.append(None)
                continue
            if floating:
                value = java_double_decimal_text(value)
            if integer:
                value = Decimal(value)
            if floating or text:
                if _DECIMAL_TEXT.fullmatch(value) is None:
                    raise pa.ArrowInvalid('Invalid decimal schema-evolution value: %s' % value)
                try:
                    value = Decimal(value)
                except InvalidOperation as error:
                    raise pa.ArrowInvalid('Invalid decimal schema-evolution value: %s' % value) from error
            # BigDecimal validates the adjusted input scale, then setScale and
            # BigInteger.TEN.pow check their supported range before precision.
            # Zero bypasses the power check, but still needs a valid input scale.
            input_scale = -value.as_tuple().exponent
            if not -(2 ** 31) <= input_scale < 2 ** 31:
                raise pa.ArrowInvalid('Invalid decimal schema-evolution input scale')
            power = abs(target.scale - input_scale)
            if not value.is_zero() and (power > 2 ** 31 - 1 or 4 * power // 32 > (2 ** 31 - 1) // 32 + 1):
                raise pa.ArrowInvalid("Decimal scale conversion exceeds Java's supported range")
            # Avoid quantizing values whose integer part already overflows.
            if not value.is_zero() and value.adjusted() + target.scale + 1 > target.precision:
                values.append(None)
                continue
            try:
                rounded = value.quantize(quantum, rounding=ROUND_HALF_UP)
            except InvalidOperation as error:
                raise pa.ArrowInvalid('Invalid decimal schema-evolution value: %s' % value) from error
            values.append(rounded if len(rounded.as_tuple().digits) <= target.precision else None)
    return pa.array(values, type=target)
