/*
 * This file is part of the Micro Python 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 "py/nlr.h"
#include "py/runtime0.h"
#include "py/runtime.h"

/******************************************************************************/
/* range iterator                                                             */

typedef struct _mp_obj_range_it_t {
    mp_obj_base_t base;
    // TODO make these values generic objects or something
    mp_int_t cur;
    mp_int_t stop;
    mp_int_t step;
} mp_obj_range_it_t;

STATIC mp_obj_t range_it_iternext(mp_obj_t o_in) {
    mp_obj_range_it_t *o = MP_OBJ_TO_PTR(o_in);
    if ((o->step > 0 && o->cur < o->stop) || (o->step < 0 && o->cur > o->stop)) {
        mp_obj_t o_out = MP_OBJ_NEW_SMALL_INT(o->cur);
        o->cur += o->step;
        return o_out;
    } else {
        return MP_OBJ_STOP_ITERATION;
    }
}

STATIC const mp_obj_type_t range_it_type = {
    { &mp_type_type },
    .name = MP_QSTR_iterator,
    .getiter = mp_identity,
    .iternext = range_it_iternext,
};

STATIC mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t step) {
    mp_obj_range_it_t *o = m_new_obj(mp_obj_range_it_t);
    o->base.type = &range_it_type;
    o->cur = cur;
    o->stop = stop;
    o->step = step;
    return MP_OBJ_FROM_PTR(o);
}

/******************************************************************************/
/* range                                                                      */

typedef struct _mp_obj_range_t {
    mp_obj_base_t base;
    // TODO make these values generic objects or something
    mp_int_t start;
    mp_int_t stop;
    mp_int_t step;
} mp_obj_range_t;

STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
    (void)kind;
    mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in);
    mp_printf(print, "range(" INT_FMT ", " INT_FMT "", self->start, self->stop);
    if (self->step == 1) {
        mp_print_str(print, ")");
    } else {
        mp_printf(print, ", " INT_FMT ")", self->step);
    }
}

STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    mp_arg_check_num(n_args, n_kw, 1, 3, false);

    mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
    o->base.type = type;
    o->start = 0;
    o->step = 1;

    if (n_args == 1) {
        o->stop = mp_obj_get_int(args[0]);
    } else {
        o->start = mp_obj_get_int(args[0]);
        o->stop = mp_obj_get_int(args[1]);
        if (n_args == 3) {
            // TODO check step is non-zero
            o->step = mp_obj_get_int(args[2]);
        }
    }

    return MP_OBJ_FROM_PTR(o);
}

STATIC mp_int_t range_len(mp_obj_range_t *self) {
    // When computing length, need to take into account step!=1 and step<0.
    mp_int_t len = self->stop - self->start + self->step;
    if (self->step > 0) {
        len -= 1;
    } else {
        len += 1;
    }
    len = len / self->step;
    if (len < 0) {
        len = 0;
    }
    return len;
}

STATIC mp_obj_t range_unary_op(mp_uint_t op, mp_obj_t self_in) {
    mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in);
    mp_int_t len = range_len(self);
    switch (op) {
        case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len > 0);
        case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len);
        default: return MP_OBJ_NULL; // op not supported
    }
}

STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
    if (value == MP_OBJ_SENTINEL) {
        // load
        mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in);
        mp_int_t len = range_len(self);
#if MICROPY_PY_BUILTINS_SLICE
        if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
            mp_bound_slice_t slice;
            mp_seq_get_fast_slice_indexes(len, index, &slice);
            mp_obj_range_t *o = m_new_obj(mp_obj_range_t);
            o->base.type = &mp_type_range;
            o->start = self->start + slice.start * self->step;
            o->stop = self->start + slice.stop * self->step;
            o->step = slice.step * self->step;
            return MP_OBJ_FROM_PTR(o);
        }
#endif
        uint index_val = mp_get_index(self->base.type, len, index, false);
        return MP_OBJ_NEW_SMALL_INT(self->start + index_val * self->step);
    } else {
        return MP_OBJ_NULL; // op not supported
    }
}

STATIC mp_obj_t range_getiter(mp_obj_t o_in) {
    mp_obj_range_t *o = MP_OBJ_TO_PTR(o_in);
    return mp_obj_new_range_iterator(o->start, o->stop, o->step);
}


#if MICROPY_PY_BUILTINS_RANGE_ATTRS
STATIC void range_attr(mp_obj_t o_in, qstr attr, mp_obj_t *dest) {
    if (dest[0] != MP_OBJ_NULL) {
        // not load attribute
        return;
    }
    mp_obj_range_t *o = MP_OBJ_TO_PTR(o_in);
    if (attr == MP_QSTR_start) {
        dest[0] = mp_obj_new_int(o->start);
    } else if (attr == MP_QSTR_stop) {
        dest[0] = mp_obj_new_int(o->stop);
    } else if (attr == MP_QSTR_step) {
        dest[0] = mp_obj_new_int(o->step);
    }
}
#endif

const mp_obj_type_t mp_type_range = {
    { &mp_type_type },
    .name = MP_QSTR_range,
    .print = range_print,
    .make_new = range_make_new,
    .unary_op = range_unary_op,
    .subscr = range_subscr,
    .getiter = range_getiter,
#if MICROPY_PY_BUILTINS_RANGE_ATTRS
    .attr = range_attr,
#endif
};
