#include <common.h>
#include <debug.h>
#include <rangesort.h>

#define PARALLEL_ARRAY_SIZE (5)

struct range_list_t {
    range_t *array;
#ifdef DEBUG
    int is_sorted;
#endif
    int array_length;
    int num_ranges;
};

range_list_t* init_range_list(void) {
    range_list_t *ranges = (range_list_t *)MALLOC(sizeof(range_list_t));

    ranges->array = (range_t *)MALLOC(PARALLEL_ARRAY_SIZE*sizeof(range_t));
    ranges->array_length = PARALLEL_ARRAY_SIZE;
    ranges->num_ranges = 0;
#ifdef DEBUG
    ranges->is_sorted = 0;
#endif
    return ranges; 
}

void destroy_range_list(range_list_t *ranges) {
    int idx;
    for (idx = 0; idx < ranges->num_ranges; idx++) {
        if (ranges->array[idx].user_dtor) {
            ASSERT(ranges->array[idx].user);
            ranges->array[idx].user_dtor(ranges->array[idx].user);
        }
    }
    FREE(ranges->array);
    FREE(ranges);
}

static inline int CONTAINS(range_t *container, range_t *contained) {
    return container->start <= contained->start && contained->length && 
    (container->start + container->length > 
     contained->start + contained->length);
}

static inline int IN_RANGE(range_t *range, GElf_Off point) {
    return 
    range->start <= point && 
    point < (range->start + range->length);
}

static inline int INTERSECT(range_t *left, range_t *right) {
    return 
    (IN_RANGE(left, right->start) && 
     IN_RANGE(right, left->start + left->length)) ||
    (IN_RANGE(right, left->start) && 
     IN_RANGE(left, right->start + right->length));
}

static int range_cmp_for_search(const void *l, const void *r) {
    range_t *left = (range_t *)l, *right = (range_t *)r;
    if (INTERSECT(left, right) ||
        CONTAINS(left, right) ||
        CONTAINS(right, left)) {
        return 0;
    }

    /* elfcopy.c checks that the start of a section begins at or
       after end of the previous section in the sorted list.  So we need
       to be careful about empty sections. */
    if (left->start != right->start)
        return left->start - right->start;
    else {
        ASSERT(left->length == 0 || right->length == 0);
        return left->length - right->length;
    }
}

static inline void run_checks(const void *l, const void *r) {
    range_t *left = (range_t *)l, *right = (range_t *)r;
    if (CONTAINS(left, right)) {
        if (left->err_fn)
            left->err_fn(ERROR_CONTAINS, left, right);
        FAILIF(1, "Range sorting error: [%lld, %lld) contains [%lld, %lld)!\n",
               left->start, left->start + left->length,
               right->start, right->start + right->length);
    }
    if (CONTAINS(right, left)) {
        if (right->err_fn)
            right->err_fn(ERROR_CONTAINS, left, right);
        FAILIF(1, "Range sorting error: [%lld, %lld) contains [%lld, %lld)!\n",
               right->start, right->start + right->length,
               left->start, left->start + left->length);
    }
    if (INTERSECT(left, right)) {
        if (left->err_fn)
            left->err_fn(ERROR_OVERLAPS, left, right);
        FAILIF(1, "Range sorting error: [%lld, %lld)and [%lld, %lld) intersect!\n",
               left->start, left->start + left->length,
               right->start, right->start + right->length);
    }
}

static int range_cmp(const void *l, const void *r) {
    run_checks(l, r);
    range_t *left = (range_t *)l, *right = (range_t *)r;

    /* elfcopy.c checks that the start of a section begins at or
       after end of the previous section in the sorted list.  So we need
       to be careful about empty sections. */
    if (left->start != right->start)
        return left->start - right->start;
    else {
        ASSERT(left->length == 0 || right->length == 0);
        return left->length - right->length;
    }
}

void add_unique_range_nosort(
                            range_list_t *ranges, 
                            GElf_Off start, 
                            GElf_Off length, 
                            void *user,
                            void (*err_fn)(range_error_t, range_t *, range_t *),
                            void (*user_dtor)(void * )) 
{
    if (ranges->num_ranges == ranges->array_length) {
        ranges->array_length += PARALLEL_ARRAY_SIZE;
        ranges->array = REALLOC(ranges->array, 
                                ranges->array_length*sizeof(range_t));
    }
    ranges->array[ranges->num_ranges].start  = start;
    ranges->array[ranges->num_ranges].length = length;
    ranges->array[ranges->num_ranges].user   = user;
    ranges->array[ranges->num_ranges].err_fn = err_fn;
    ranges->array[ranges->num_ranges].user_dtor = user_dtor;
    ranges->num_ranges++;
}

range_list_t *sort_ranges(range_list_t *ranges) {
    if (ranges->num_ranges > 1)
        qsort(ranges->array, ranges->num_ranges, sizeof(range_t), range_cmp);
    ranges->is_sorted = 1;
    return ranges;
}

range_t *find_range(range_list_t *ranges, GElf_Off value) {
#if 1
    int i;
    for (i = 0; i < ranges->num_ranges; i++) {
        if (ranges->array[i].start <= value && 
            value < ranges->array[i].start + ranges->array[i].length)
            return ranges->array + i;
    }
    return NULL;
#else
    ASSERT(ranges->is_sorted); /* The range list must be sorted */
    range_t lookup;
    lookup.start = value;
    lookup.length = 0;
    return 
    (range_t *)bsearch(&lookup, 
                       ranges->array, ranges->num_ranges, sizeof(range_t), 
                       range_cmp_for_search);
#endif
}

int get_num_ranges(const range_list_t *ranges)
{
    return ranges->num_ranges;
}

range_t *get_sorted_ranges(const range_list_t *ranges, int *num_ranges) {
    ASSERT(ranges->is_sorted); /* The range list must be sorted */
    if (num_ranges) {
        *num_ranges = ranges->num_ranges;
    }
    return ranges->array;
}

GElf_Off get_last_address(const range_list_t *ranges) {
    ASSERT(ranges->num_ranges);
    return 
    ranges->array[ranges->num_ranges-1].start +
    ranges->array[ranges->num_ranges-1].length;
}

static void handle_range_error(range_error_t err, 
                               range_t *left, range_t *right) {
    switch (err) {
    case ERROR_CONTAINS:
        ERROR("ERROR: section (%lld, %lld bytes) contains "
              "section (%lld, %lld bytes)\n",
              left->start, left->length,
              right->start, right->length);
        break;
    case ERROR_OVERLAPS:
        ERROR("ERROR: Section (%lld, %lld bytes) intersects "
              "section (%lld, %lld bytes)\n",
              left->start, left->length,
              right->start, right->length);
        break;
    default:
        ASSERT(!"Unknown range error code!");
    }

    FAILIF(1, "Range error.\n");
}

static void destroy_contiguous_range_info(void *user) {
    contiguous_range_info_t *info = (contiguous_range_info_t *)user;
    FREE(info->ranges);
    FREE(info);
}

static void handle_contiguous_range_error(range_error_t err, 
                                          range_t *left, 
                                          range_t *right)
{
    contiguous_range_info_t *left_data = 
        (contiguous_range_info_t *)left->user;
    ASSERT(left_data);
    contiguous_range_info_t *right_data = 
        (contiguous_range_info_t *)right->user;
    ASSERT(right_data);

    PRINT("Contiguous-range overlap error.  Printing contained ranges:\n");
    int cnt;
    PRINT("\tLeft ranges:\n");
    for (cnt = 0; cnt < left_data->num_ranges; cnt++) {
        PRINT("\t\t[%lld, %lld)\n",
              left_data->ranges[cnt].start,
              left_data->ranges[cnt].start + left_data->ranges[cnt].length);
    }
    PRINT("\tRight ranges:\n");
    for (cnt = 0; cnt < right_data->num_ranges; cnt++) {
        PRINT("\t\t[%lld, %lld)\n",
              right_data->ranges[cnt].start,
              right_data->ranges[cnt].start + right_data->ranges[cnt].length);
    }

    handle_range_error(err, left, right);
}

range_list_t* get_contiguous_ranges(const range_list_t *input)
{
    ASSERT(input);
    FAILIF(!input->is_sorted, 
           "get_contiguous_ranges(): input range list is not sorted!\n");

    range_list_t* ret = init_range_list();
    int num_ranges;
    range_t *ranges = get_sorted_ranges(input, &num_ranges);

    int end_idx = 0;
    while (end_idx < num_ranges) {
        int start_idx = end_idx++;
        int old_end_idx = start_idx;
        int total_length = ranges[start_idx].length;
        while (end_idx < num_ranges) {
            if (ranges[old_end_idx].start + ranges[old_end_idx].length !=
                ranges[end_idx].start)
                break;
            old_end_idx = end_idx++;
            total_length += ranges[old_end_idx].length;
        }

        contiguous_range_info_t *user = 
            (contiguous_range_info_t *)MALLOC(sizeof(contiguous_range_info_t));
        user->num_ranges = end_idx - start_idx;
        user->ranges = (range_t *)MALLOC(user->num_ranges * sizeof(range_t));
        int i;
        for (i = 0; i < end_idx - start_idx; i++)
            user->ranges[i] = ranges[start_idx + i];
        add_unique_range_nosort(ret, 
                                ranges[start_idx].start,
                                total_length,
                                user,
                                handle_contiguous_range_error,
                                destroy_contiguous_range_info);
    }

    return ret;
}

range_list_t* subtract_ranges(const range_list_t *r, const range_list_t *s)
{
    ASSERT(r);  ASSERT(r->is_sorted);
    ASSERT(s);  ASSERT(s->is_sorted);

    range_list_t *result = init_range_list();

    int r_num_ranges, r_idx;
    range_t *r_ranges = get_sorted_ranges(r, &r_num_ranges);
    ASSERT(r_ranges);

    int s_num_ranges, s_idx;
    range_t *s_ranges = get_sorted_ranges(s, &s_num_ranges);
    ASSERT(s_ranges);

    s_idx = 0;
    for (r_idx = 0; r_idx < r_num_ranges; r_idx++) {
        GElf_Off last_start = r_ranges[r_idx].start;
        for (; s_idx < s_num_ranges; s_idx++) {
            if (CONTAINS(&r_ranges[r_idx], &s_ranges[s_idx])) {
                if (last_start == 
                    r_ranges[r_idx].start + r_ranges[r_idx].length) {
                    break;
                }
                if (last_start == s_ranges[s_idx].start) {
                    last_start += s_ranges[s_idx].length;
                    continue;
                }
                INFO("Adding subtracted range [%lld, %lld)\n",
                     last_start,
                     s_ranges[s_idx].start);
                add_unique_range_nosort(
                    result, 
                    last_start,
                    s_ranges[s_idx].start - last_start,
                    NULL,
                    NULL,
                    NULL);
                last_start = s_ranges[s_idx].start + s_ranges[s_idx].length;
            } else {
                ASSERT(!INTERSECT(&r_ranges[r_idx], &s_ranges[s_idx]));
                break;
            }
        } /* while (s_idx < s_num_ranges) */
    } /* for (r_idx = 0; r_idx < r_num_ranges; r_idx++) */

    return result;
}


