/**
 * Copyright 2013, GitHub, Inc
 * Copyright 2009-2013, Daniel Lemire, Cliff Moon,
 *	David McIntosh, Robert Becho, Google Inc. and Veronika Zenz
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "git-compat-util.h"
#include "ewok.h"

#define EWAH_MASK(x) ((eword_t)1 << (x % BITS_IN_EWORD))
#define EWAH_BLOCK(x) (x / BITS_IN_EWORD)

struct bitmap *bitmap_word_alloc(size_t word_alloc)
{
	struct bitmap *bitmap = xmalloc(sizeof(struct bitmap));
	CALLOC_ARRAY(bitmap->words, word_alloc);
	bitmap->word_alloc = word_alloc;
	return bitmap;
}

struct bitmap *bitmap_new(void)
{
	return bitmap_word_alloc(32);
}

struct bitmap *bitmap_dup(const struct bitmap *src)
{
	struct bitmap *dst = bitmap_word_alloc(src->word_alloc);
	COPY_ARRAY(dst->words, src->words, src->word_alloc);
	return dst;
}

static void bitmap_grow(struct bitmap *self, size_t word_alloc)
{
	size_t old_size = self->word_alloc;
	ALLOC_GROW(self->words, word_alloc, self->word_alloc);
	MEMZERO_ARRAY(self->words + old_size, self->word_alloc - old_size);
}

void bitmap_set(struct bitmap *self, size_t pos)
{
	size_t block = EWAH_BLOCK(pos);

	bitmap_grow(self, block + 1);
	self->words[block] |= EWAH_MASK(pos);
}

void bitmap_unset(struct bitmap *self, size_t pos)
{
	size_t block = EWAH_BLOCK(pos);

	if (block < self->word_alloc)
		self->words[block] &= ~EWAH_MASK(pos);
}

int bitmap_get(struct bitmap *self, size_t pos)
{
	size_t block = EWAH_BLOCK(pos);
	return block < self->word_alloc &&
		(self->words[block] & EWAH_MASK(pos)) != 0;
}

struct ewah_bitmap *bitmap_to_ewah(struct bitmap *bitmap)
{
	struct ewah_bitmap *ewah = ewah_new();
	size_t i, running_empty_words = 0;
	eword_t last_word = 0;

	for (i = 0; i < bitmap->word_alloc; ++i) {
		if (bitmap->words[i] == 0) {
			running_empty_words++;
			continue;
		}

		if (last_word != 0)
			ewah_add(ewah, last_word);

		if (running_empty_words > 0) {
			ewah_add_empty_words(ewah, 0, running_empty_words);
			running_empty_words = 0;
		}

		last_word = bitmap->words[i];
	}

	ewah_add(ewah, last_word);
	return ewah;
}

struct bitmap *ewah_to_bitmap(struct ewah_bitmap *ewah)
{
	struct bitmap *bitmap = bitmap_new();
	struct ewah_iterator it;
	eword_t blowup;
	size_t i = 0;

	ewah_iterator_init(&it, ewah);

	while (ewah_iterator_next(&blowup, &it)) {
		ALLOC_GROW(bitmap->words, i + 1, bitmap->word_alloc);
		bitmap->words[i++] = blowup;
	}

	bitmap->word_alloc = i;
	return bitmap;
}

void bitmap_and_not(struct bitmap *self, struct bitmap *other)
{
	const size_t count = (self->word_alloc < other->word_alloc) ?
		self->word_alloc : other->word_alloc;

	size_t i;

	for (i = 0; i < count; ++i)
		self->words[i] &= ~other->words[i];
}

void bitmap_or(struct bitmap *self, const struct bitmap *other)
{
	size_t i;

	bitmap_grow(self, other->word_alloc);
	for (i = 0; i < other->word_alloc; i++)
		self->words[i] |= other->words[i];
}

int ewah_bitmap_is_subset(struct ewah_bitmap *self, struct bitmap *other)
{
	struct ewah_iterator it;
	eword_t word;
	size_t i;

	ewah_iterator_init(&it, self);

	for (i = 0; i < other->word_alloc; i++) {
		if (!ewah_iterator_next(&word, &it)) {
			/*
			 * If we reached the end of `self`, and haven't
			 * rejected `self` as a possible subset of
			 * `other` yet, then we are done and `self` is
			 * indeed a subset of `other`.
			 */
			return 1;
		}
		if (word & ~other->words[i]) {
			/*
			 * Otherwise, compare the next two pairs of
			 * words. If the word from `self` has bit(s) not
			 * in the word from `other`, `self` is not a
			 * subset of `other`.
			 */
			return 0;
		}
	}

	/*
	 * If we got to this point, there may be zero or more words
	 * remaining in `self`, with no remaining words left in `other`.
	 * If there are any bits set in the remaining word(s) in `self`,
	 * then `self` is not a subset of `other`.
	 */
	while (ewah_iterator_next(&word, &it))
		if (word)
			return 0;

	/* `self` is definitely a subset of `other` */
	return 1;
}

void bitmap_or_ewah(struct bitmap *self, struct ewah_bitmap *other)
{
	size_t original_size = self->word_alloc;
	size_t other_final = (other->bit_size / BITS_IN_EWORD) + 1;
	size_t i = 0;
	struct ewah_iterator it;
	eword_t word;

	if (self->word_alloc < other_final) {
		self->word_alloc = other_final;
		REALLOC_ARRAY(self->words, self->word_alloc);
		MEMZERO_ARRAY(self->words + original_size,
			      self->word_alloc - original_size);
	}

	ewah_iterator_init(&it, other);

	while (ewah_iterator_next(&word, &it))
		self->words[i++] |= word;
}

size_t bitmap_popcount(struct bitmap *self)
{
	size_t i, count = 0;

	for (i = 0; i < self->word_alloc; ++i)
		count += ewah_bit_popcount64(self->words[i]);

	return count;
}

size_t ewah_bitmap_popcount(struct ewah_bitmap *self)
{
	struct ewah_iterator it;
	eword_t word;
	size_t count = 0;

	ewah_iterator_init(&it, self);

	while (ewah_iterator_next(&word, &it))
		count += ewah_bit_popcount64(word);

	return count;
}

int bitmap_is_empty(struct bitmap *self)
{
	size_t i;
	for (i = 0; i < self->word_alloc; i++)
		if (self->words[i])
			return 0;
	return 1;
}

int bitmap_equals(struct bitmap *self, struct bitmap *other)
{
	struct bitmap *big, *small;
	size_t i;

	if (self->word_alloc < other->word_alloc) {
		small = self;
		big = other;
	} else {
		small = other;
		big = self;
	}

	for (i = 0; i < small->word_alloc; ++i) {
		if (small->words[i] != big->words[i])
			return 0;
	}

	for (; i < big->word_alloc; ++i) {
		if (big->words[i] != 0)
			return 0;
	}

	return 1;
}

int bitmap_equals_ewah(struct bitmap *self, struct ewah_bitmap *other)
{
	struct ewah_iterator it;
	eword_t word;
	size_t i = 0;

	ewah_iterator_init(&it, other);

	while (ewah_iterator_next(&word, &it))
		if (word != (i < self->word_alloc ? self->words[i++] : 0))
			return 0;

	for (; i < self->word_alloc; i++)
		if (self->words[i])
			return 0;

	return 1;
}

int bitmap_is_subset(struct bitmap *self, struct bitmap *other)
{
	size_t common_size, i;

	if (self->word_alloc < other->word_alloc)
		common_size = self->word_alloc;
	else {
		common_size = other->word_alloc;
		for (i = common_size; i < self->word_alloc; i++) {
			if (self->words[i])
				return 1;
		}
	}

	for (i = 0; i < common_size; i++) {
		if (self->words[i] & ~other->words[i])
			return 1;
	}
	return 0;
}

void bitmap_free(struct bitmap *bitmap)
{
	if (!bitmap)
		return;

	free(bitmap->words);
	free(bitmap);
}
