/**
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
#include "git-compat-util.h"
#include "ewok.h"
#include "strbuf.h"

int ewah_serialize_native(struct ewah_bitmap *self, int fd)
{
	uint32_t write32;
	size_t to_write = self->buffer_size * 8;

	/* 32 bit -- bit size for the map */
	write32 = (uint32_t)self->bit_size;
	if (write(fd, &write32, 4) != 4)
		return -1;

	/** 32 bit -- number of compressed 64-bit words */
	write32 = (uint32_t)self->buffer_size;
	if (write(fd, &write32, 4) != 4)
		return -1;

	if (write(fd, self->buffer, to_write) != to_write)
		return -1;

	/** 32 bit -- position for the RLW */
	write32 = self->rlw - self->buffer;
	if (write(fd, &write32, 4) != 4)
		return -1;

	return (3 * 4) + to_write;
}

int ewah_serialize_to(struct ewah_bitmap *self,
		      int (*write_fun)(void *, const void *, size_t),
		      void *data)
{
	size_t i;
	eword_t dump[2048];
	const size_t words_per_dump = sizeof(dump) / sizeof(eword_t);
	uint32_t bitsize, word_count, rlw_pos;

	const eword_t *buffer;
	size_t words_left;

	/* 32 bit -- bit size for the map */
	bitsize =  htonl((uint32_t)self->bit_size);
	if (write_fun(data, &bitsize, 4) != 4)
		return -1;

	/** 32 bit -- number of compressed 64-bit words */
	word_count =  htonl((uint32_t)self->buffer_size);
	if (write_fun(data, &word_count, 4) != 4)
		return -1;

	/** 64 bit x N -- compressed words */
	buffer = self->buffer;
	words_left = self->buffer_size;

	while (words_left >= words_per_dump) {
		for (i = 0; i < words_per_dump; ++i, ++buffer)
			dump[i] = htonll(*buffer);

		if (write_fun(data, dump, sizeof(dump)) != sizeof(dump))
			return -1;

		words_left -= words_per_dump;
	}

	if (words_left) {
		for (i = 0; i < words_left; ++i, ++buffer)
			dump[i] = htonll(*buffer);

		if (write_fun(data, dump, words_left * 8) != words_left * 8)
			return -1;
	}

	/** 32 bit -- position for the RLW */
	rlw_pos = (uint8_t*)self->rlw - (uint8_t *)self->buffer;
	rlw_pos = htonl(rlw_pos / sizeof(eword_t));

	if (write_fun(data, &rlw_pos, 4) != 4)
		return -1;

	return (3 * 4) + (self->buffer_size * 8);
}

static int write_helper(void *fd, const void *buf, size_t len)
{
	return write((intptr_t)fd, buf, len);
}

int ewah_serialize(struct ewah_bitmap *self, int fd)
{
	return ewah_serialize_to(self, write_helper, (void *)(intptr_t)fd);
}

static int write_strbuf(void *user_data, const void *data, size_t len)
{
	struct strbuf *sb = user_data;
	strbuf_add(sb, data, len);
	return len;
}

int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *sb)
{
	return ewah_serialize_to(self, write_strbuf, sb);
}

int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
{
	const uint8_t *ptr = map;
	size_t i;

	self->bit_size = get_be32(ptr);
	ptr += sizeof(uint32_t);

	self->buffer_size = self->alloc_size = get_be32(ptr);
	ptr += sizeof(uint32_t);

	REALLOC_ARRAY(self->buffer, self->alloc_size);

	/*
	 * Copy the raw data for the bitmap as a whole chunk;
	 * if we're in a little-endian platform, we'll perform
	 * the endianness conversion in a separate pass to ensure
	 * we're loading 8-byte aligned words.
	 */
	memcpy(self->buffer, ptr, self->buffer_size * sizeof(eword_t));
	ptr += self->buffer_size * sizeof(eword_t);

	for (i = 0; i < self->buffer_size; ++i)
		self->buffer[i] = ntohll(self->buffer[i]);

	self->rlw = self->buffer + get_be32(ptr);

	return (3 * 4) + (self->buffer_size * 8);
}

int ewah_deserialize(struct ewah_bitmap *self, int fd)
{
	size_t i;
	eword_t dump[2048];
	const size_t words_per_dump = sizeof(dump) / sizeof(eword_t);
	uint32_t bitsize, word_count, rlw_pos;

	eword_t *buffer = NULL;
	size_t words_left;

	ewah_clear(self);

	/* 32 bit -- bit size for the map */
	if (read(fd, &bitsize, 4) != 4)
		return -1;

	self->bit_size = (size_t)ntohl(bitsize);

	/** 32 bit -- number of compressed 64-bit words */
	if (read(fd, &word_count, 4) != 4)
		return -1;

	self->buffer_size = self->alloc_size = (size_t)ntohl(word_count);
	REALLOC_ARRAY(self->buffer, self->alloc_size);

	/** 64 bit x N -- compressed words */
	buffer = self->buffer;
	words_left = self->buffer_size;

	while (words_left >= words_per_dump) {
		if (read(fd, dump, sizeof(dump)) != sizeof(dump))
			return -1;

		for (i = 0; i < words_per_dump; ++i, ++buffer)
			*buffer = ntohll(dump[i]);

		words_left -= words_per_dump;
	}

	if (words_left) {
		if (read(fd, dump, words_left * 8) != words_left * 8)
			return -1;

		for (i = 0; i < words_left; ++i, ++buffer)
			*buffer = ntohll(dump[i]);
	}

	/** 32 bit -- position for the RLW */
	if (read(fd, &rlw_pos, 4) != 4)
		return -1;

	self->rlw = self->buffer + ntohl(rlw_pos);
	return 0;
}
