/*
 * csum-file.c
 *
 * Copyright (C) 2005 Linus Torvalds
 *
 * Simple file write infrastructure for writing SHA1-summed
 * files. Useful when you write a file that you want to be
 * able to verify hasn't been messed with afterwards.
 */

#include "git-compat-util.h"
#include "csum-file.h"
#include "git-zlib.h"
#include "hash.h"
#include "progress.h"

static void verify_buffer_or_die(struct hashfile *f,
				 const void *buf,
				 unsigned int count)
{
	ssize_t ret = read_in_full(f->check_fd, f->check_buffer, count);

	if (ret < 0)
		die_errno("%s: sha1 file read error", f->name);
	if ((size_t)ret != count)
		die("%s: sha1 file truncated", f->name);
	if (memcmp(buf, f->check_buffer, count))
		die("sha1 file '%s' validation error", f->name);
}

static void flush(struct hashfile *f, const void *buf, unsigned int count)
{
	if (0 <= f->check_fd && count)
		verify_buffer_or_die(f, buf, count);

	if (write_in_full(f->fd, buf, count) < 0) {
		if (errno == ENOSPC)
			die("sha1 file '%s' write error. Out of diskspace", f->name);
		die_errno("sha1 file '%s' write error", f->name);
	}

	f->total += count;
	display_throughput(f->tp, f->total);
}

void hashflush(struct hashfile *f)
{
	unsigned offset = f->offset;

	if (offset) {
		if (!f->skip_hash)
			git_hash_update(&f->ctx, f->buffer, offset);
		flush(f, f->buffer, offset);
		f->offset = 0;
	}
}

void free_hashfile(struct hashfile *f)
{
	free(f->buffer);
	free(f->check_buffer);
	free(f);
}

int finalize_hashfile(struct hashfile *f, unsigned char *result,
		      enum fsync_component component, unsigned int flags)
{
	int fd;

	hashflush(f);

	if (f->skip_hash)
		hashclr(f->buffer, f->algop);
	else
		git_hash_final(f->buffer, &f->ctx);

	if (result)
		hashcpy(result, f->buffer, f->algop);
	if (flags & CSUM_HASH_IN_STREAM)
		flush(f, f->buffer, f->algop->rawsz);
	if (flags & CSUM_FSYNC)
		fsync_component_or_die(component, f->fd, f->name);
	if (flags & CSUM_CLOSE) {
		if (close(f->fd))
			die_errno("%s: sha1 file error on close", f->name);
		fd = 0;
	} else
		fd = f->fd;
	if (0 <= f->check_fd) {
		char discard;
		int cnt = read_in_full(f->check_fd, &discard, 1);
		if (cnt < 0)
			die_errno("%s: error when reading the tail of sha1 file",
				  f->name);
		if (cnt)
			die("%s: sha1 file has trailing garbage", f->name);
		if (close(f->check_fd))
			die_errno("%s: sha1 file error on close", f->name);
	}
	free_hashfile(f);
	return fd;
}

void discard_hashfile(struct hashfile *f)
{
	if (0 <= f->check_fd)
		close(f->check_fd);
	if (0 <= f->fd)
		close(f->fd);
	free_hashfile(f);
}

void hashwrite(struct hashfile *f, const void *buf, uint32_t count)
{
	while (count) {
		unsigned left = f->buffer_len - f->offset;
		unsigned nr = count > left ? left : count;

		if (f->do_crc)
			f->crc32 = crc32(f->crc32, buf, nr);

		if (nr == f->buffer_len) {
			/*
			 * Flush a full batch worth of data directly
			 * from the input, skipping the memcpy() to
			 * the hashfile's buffer. In this block,
			 * f->offset is necessarily zero.
			 */
			if (!f->skip_hash)
				git_hash_update(&f->ctx, buf, nr);
			flush(f, buf, nr);
		} else {
			/*
			 * Copy to the hashfile's buffer, flushing only
			 * if it became full.
			 */
			memcpy(f->buffer + f->offset, buf, nr);
			f->offset += nr;
			left -= nr;
			if (!left)
				hashflush(f);
		}

		count -= nr;
		buf = (char *) buf + nr;
	}
}

struct hashfile *hashfd_check(const struct git_hash_algo *algop,
			      const char *name)
{
	int sink, check;
	struct hashfile *f;

	sink = xopen("/dev/null", O_WRONLY);
	check = xopen(name, O_RDONLY);
	f = hashfd(algop, sink, name);
	f->check_fd = check;
	f->check_buffer = xmalloc(f->buffer_len);

	return f;
}

struct hashfile *hashfd_ext(const struct git_hash_algo *algop,
			    int fd, const char *name,
			    const struct hashfd_options *opts)
{
	struct hashfile *f = xmalloc(sizeof(*f));
	f->fd = fd;
	f->check_fd = -1;
	f->offset = 0;
	f->total = 0;
	f->tp = opts->progress;
	f->name = name;
	f->do_crc = 0;
	f->skip_hash = 0;

	f->algop = unsafe_hash_algo(algop);
	f->algop->init_fn(&f->ctx);

	f->buffer_len = opts->buffer_len ? opts->buffer_len : 128 * 1024;
	f->buffer = xmalloc(f->buffer_len);
	f->check_buffer = NULL;

	return f;
}

struct hashfile *hashfd(const struct git_hash_algo *algop,
			int fd, const char *name)
{
	/*
	 * Since we are not going to use a progress meter to
	 * measure the rate of data passing through this hashfile,
	 * use a larger buffer size to reduce fsync() calls.
	 */
	struct hashfd_options opts = { 0 };
	return hashfd_ext(algop, fd, name, &opts);
}

void hashfile_checkpoint_init(struct hashfile *f,
			      struct hashfile_checkpoint *checkpoint)
{
	memset(checkpoint, 0, sizeof(*checkpoint));
	f->algop->init_fn(&checkpoint->ctx);
}

void hashfile_checkpoint(struct hashfile *f, struct hashfile_checkpoint *checkpoint)
{
	hashflush(f);
	checkpoint->offset = f->total;
	git_hash_clone(&checkpoint->ctx, &f->ctx);
}

int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint)
{
	off_t offset = checkpoint->offset;

	if (ftruncate(f->fd, offset) ||
	    lseek(f->fd, offset, SEEK_SET) != offset)
		return -1;
	f->total = offset;
	git_hash_clone(&f->ctx, &checkpoint->ctx);
	f->offset = 0; /* hashflush() was called in checkpoint */
	return 0;
}

void crc32_begin(struct hashfile *f)
{
	f->crc32 = crc32(0, NULL, 0);
	f->do_crc = 1;
}

uint32_t crc32_end(struct hashfile *f)
{
	f->do_crc = 0;
	return f->crc32;
}

int hashfile_checksum_valid(const struct git_hash_algo *algop,
			    const unsigned char *data, size_t total_len)
{
	unsigned char got[GIT_MAX_RAWSZ];
	struct git_hash_ctx ctx;
	size_t data_len = total_len - algop->rawsz;

	algop = unsafe_hash_algo(algop);

	if (total_len < algop->rawsz)
		return 0; /* say "too short"? */

	algop->init_fn(&ctx);
	git_hash_update(&ctx, data, data_len);
	git_hash_final(got, &ctx);

	return hasheq(got, data + data_len, algop);
}
