/*
 * This file is part of the MicroPython project, http://micropython.org/
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2013, 2014 Damien P. George
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include "py/parsenum.h"
#include "py/runtime.h"

#if MICROPY_PY_BUILTINS_FLOAT

#include <math.h>
#include "py/formatfloat.h"

#if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D

// M_E and M_PI are not part of the math.h standard and may not be defined
#ifndef M_E
#define M_E (2.7182818284590452354)
#endif
#ifndef M_PI
#define M_PI (3.14159265358979323846)
#endif

typedef struct _mp_obj_float_t {
    mp_obj_base_t base;
    mp_float_t value;
} mp_obj_float_t;

const mp_obj_float_t mp_const_float_e_obj = {{&mp_type_float}, M_E};
const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, M_PI};

#endif

#if MICROPY_FLOAT_HIGH_QUALITY_HASH
// must return actual integer value if it fits in mp_int_t
mp_int_t mp_float_hash(mp_float_t src) {
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
typedef uint64_t mp_float_uint_t;
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
typedef uint32_t mp_float_uint_t;
#endif
    union {
        mp_float_t f;
        #if MP_ENDIANNESS_LITTLE
        struct { mp_float_uint_t frc:MP_FLOAT_FRAC_BITS, exp:MP_FLOAT_EXP_BITS, sgn:1; } p;
        #else
        struct { mp_float_uint_t sgn:1, exp:MP_FLOAT_EXP_BITS, frc:MP_FLOAT_FRAC_BITS; } p;
        #endif
        mp_float_uint_t i;
    } u = {.f = src};

    mp_int_t val;
    const int adj_exp = (int)u.p.exp - MP_FLOAT_EXP_BIAS;
    if (adj_exp < 0) {
        // value < 1; must be sure to handle 0.0 correctly (ie return 0)
        val = u.i;
    } else {
        // if adj_exp is max then: u.p.frc==0 indicates inf, else NaN
        // else: 1 <= value
        mp_float_uint_t frc = u.p.frc | ((mp_float_uint_t)1 << MP_FLOAT_FRAC_BITS);

        if (adj_exp <= MP_FLOAT_FRAC_BITS) {
            // number may have a fraction; xor the integer part with the fractional part
            val = (frc >> (MP_FLOAT_FRAC_BITS - adj_exp))
                ^ (frc & ((1 << (MP_FLOAT_FRAC_BITS - adj_exp)) - 1));
        } else if ((unsigned int)adj_exp < BITS_PER_BYTE * sizeof(mp_int_t) - 1) {
            // the number is a (big) whole integer and will fit in val's signed-width
            val = (mp_int_t)frc << (adj_exp - MP_FLOAT_FRAC_BITS);
        } else {
            // integer part will overflow val's width so just use what bits we can
            val = frc;
        }
    }

    if (u.p.sgn) {
        val = -val;
    }

    return val;
}
#endif

STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
    (void)kind;
    mp_float_t o_val = mp_obj_float_get(o_in);
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
    char buf[16];
    #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C
    const int precision = 6;
    #else
    const int precision = 7;
    #endif
#else
    char buf[32];
    const int precision = 16;
#endif
    mp_format_float(o_val, buf, sizeof(buf), 'g', precision, '\0');
    mp_print_str(print, buf);
    if (strchr(buf, '.') == NULL && strchr(buf, 'e') == NULL && strchr(buf, 'n') == NULL) {
        // Python floats always have decimal point (unless inf or nan)
        mp_print_str(print, ".0");
    }
}

STATIC mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    (void)type_in;
    mp_arg_check_num(n_args, n_kw, 0, 1, false);

    switch (n_args) {
        case 0:
            return mp_obj_new_float(0);

        case 1:
        default: {
            mp_buffer_info_t bufinfo;
            if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_READ)) {
                // a textual representation, parse it
                return mp_parse_num_decimal(bufinfo.buf, bufinfo.len, false, false, NULL);
            } else if (mp_obj_is_float(args[0])) {
                // a float, just return it
                return args[0];
            } else {
                // something else, try to cast it to a float
                return mp_obj_new_float(mp_obj_get_float(args[0]));
            }
        }
    }
}

STATIC mp_obj_t float_unary_op(mp_unary_op_t op, mp_obj_t o_in) {
    mp_float_t val = mp_obj_float_get(o_in);
    switch (op) {
        case MP_UNARY_OP_BOOL: return mp_obj_new_bool(val != 0);
        case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT(mp_float_hash(val));
        case MP_UNARY_OP_POSITIVE: return o_in;
        case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val);
        case MP_UNARY_OP_ABS: {
            // TODO check for NaN etc
            if (val < 0) {
                return mp_obj_new_float(-val);
            } else {
                return o_in;
            }
        }
        default: return MP_OBJ_NULL; // op not supported
    }
}

STATIC mp_obj_t float_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
    mp_float_t lhs_val = mp_obj_float_get(lhs_in);
#if MICROPY_PY_BUILTINS_COMPLEX
    if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) {
        return mp_obj_complex_binary_op(op, lhs_val, 0, rhs_in);
    } else
#endif
    {
        return mp_obj_float_binary_op(op, lhs_val, rhs_in);
    }
}

const mp_obj_type_t mp_type_float = {
    { &mp_type_type },
    .name = MP_QSTR_float,
    .print = float_print,
    .make_new = float_make_new,
    .unary_op = float_unary_op,
    .binary_op = float_binary_op,
};

#if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D

mp_obj_t mp_obj_new_float(mp_float_t value) {
    mp_obj_float_t *o = m_new(mp_obj_float_t, 1);
    o->base.type = &mp_type_float;
    o->value = value;
    return MP_OBJ_FROM_PTR(o);
}

mp_float_t mp_obj_float_get(mp_obj_t self_in) {
    assert(mp_obj_is_float(self_in));
    mp_obj_float_t *self = MP_OBJ_TO_PTR(self_in);
    return self->value;
}

#endif

STATIC void mp_obj_float_divmod(mp_float_t *x, mp_float_t *y) {
    // logic here follows that of CPython
    // https://docs.python.org/3/reference/expressions.html#binary-arithmetic-operations
    // x == (x//y)*y + (x%y)
    // divmod(x, y) == (x//y, x%y)
    mp_float_t mod = MICROPY_FLOAT_C_FUN(fmod)(*x, *y);
    mp_float_t div = (*x - mod) / *y;

    // Python specs require that mod has same sign as second operand
    if (mod == 0.0) {
        mod = MICROPY_FLOAT_C_FUN(copysign)(0.0, *y);
    } else {
        if ((mod < 0.0) != (*y < 0.0)) {
            mod += *y;
            div -= 1.0;
        }
    }

    mp_float_t floordiv;
    if (div == 0.0) {
        // if division is zero, take the correct sign of zero
        floordiv = MICROPY_FLOAT_C_FUN(copysign)(0.0, *x / *y);
    } else {
        // Python specs require that x == (x//y)*y + (x%y)
        floordiv = MICROPY_FLOAT_C_FUN(floor)(div);
        if (div - floordiv > 0.5) {
            floordiv += 1.0;
        }
    }

    // return results
    *x = floordiv;
    *y = mod;
}

mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t rhs_in) {
    mp_float_t rhs_val;
    if (!mp_obj_get_float_maybe(rhs_in, &rhs_val)) {
        return MP_OBJ_NULL; // op not supported
    }

    switch (op) {
        case MP_BINARY_OP_ADD:
        case MP_BINARY_OP_INPLACE_ADD: lhs_val += rhs_val; break;
        case MP_BINARY_OP_SUBTRACT:
        case MP_BINARY_OP_INPLACE_SUBTRACT: lhs_val -= rhs_val; break;
        case MP_BINARY_OP_MULTIPLY:
        case MP_BINARY_OP_INPLACE_MULTIPLY: lhs_val *= rhs_val; break;
        case MP_BINARY_OP_FLOOR_DIVIDE:
        case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE:
            if (rhs_val == 0) {
                zero_division_error:
                mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero");
            }
            // Python specs require that x == (x//y)*y + (x%y) so we must
            // call divmod to compute the correct floor division, which
            // returns the floor divide in lhs_val.
            mp_obj_float_divmod(&lhs_val, &rhs_val);
            break;
        case MP_BINARY_OP_TRUE_DIVIDE:
        case MP_BINARY_OP_INPLACE_TRUE_DIVIDE:
            if (rhs_val == 0) {
                goto zero_division_error;
            }
            lhs_val /= rhs_val;
            break;
        case MP_BINARY_OP_MODULO:
        case MP_BINARY_OP_INPLACE_MODULO:
            if (rhs_val == 0) {
                goto zero_division_error;
            }
            lhs_val = MICROPY_FLOAT_C_FUN(fmod)(lhs_val, rhs_val);
            // Python specs require that mod has same sign as second operand
            if (lhs_val == 0.0) {
                lhs_val = MICROPY_FLOAT_C_FUN(copysign)(0.0, rhs_val);
            } else {
                if ((lhs_val < 0.0) != (rhs_val < 0.0)) {
                    lhs_val += rhs_val;
                }
            }
            break;
        case MP_BINARY_OP_POWER:
        case MP_BINARY_OP_INPLACE_POWER:
            if (lhs_val == 0 && rhs_val < 0) {
                goto zero_division_error;
            }
            if (lhs_val < 0 && rhs_val != MICROPY_FLOAT_C_FUN(floor)(rhs_val)) {
                #if MICROPY_PY_BUILTINS_COMPLEX
                return mp_obj_complex_binary_op(MP_BINARY_OP_POWER, lhs_val, 0, rhs_in);
                #else
                mp_raise_ValueError("complex values not supported");
                #endif
            }
            lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val);
            break;
        case MP_BINARY_OP_DIVMOD: {
            if (rhs_val == 0) {
                goto zero_division_error;
            }
            mp_obj_float_divmod(&lhs_val, &rhs_val);
            mp_obj_t tuple[2] = {
                mp_obj_new_float(lhs_val),
                mp_obj_new_float(rhs_val),
            };
            return mp_obj_new_tuple(2, tuple);
        }
        case MP_BINARY_OP_LESS: return mp_obj_new_bool(lhs_val < rhs_val);
        case MP_BINARY_OP_MORE: return mp_obj_new_bool(lhs_val > rhs_val);
        case MP_BINARY_OP_EQUAL: return mp_obj_new_bool(lhs_val == rhs_val);
        case MP_BINARY_OP_LESS_EQUAL: return mp_obj_new_bool(lhs_val <= rhs_val);
        case MP_BINARY_OP_MORE_EQUAL: return mp_obj_new_bool(lhs_val >= rhs_val);

        default:
            return MP_OBJ_NULL; // op not supported
    }
    return mp_obj_new_float(lhs_val);
}

#endif // MICROPY_PY_BUILTINS_FLOAT
