/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
#include "common.h"
#include "filebuf.h"
#include "fileops.h"

static const size_t WRITE_BUFFER_SIZE = (4096 * 2);

enum buferr_t {
	BUFERR_OK = 0,
	BUFERR_WRITE,
	BUFERR_ZLIB,
	BUFERR_MEM
};

#define ENSURE_BUF_OK(buf) if ((buf)->last_error != BUFERR_OK) { return -1; }

static int verify_last_error(git_filebuf *file)
{
	switch (file->last_error) {
	case BUFERR_WRITE:
		giterr_set(GITERR_OS, "Failed to write out file");
		return -1;

	case BUFERR_MEM:
		giterr_set_oom();
		return -1;

	case BUFERR_ZLIB:
		giterr_set(GITERR_ZLIB,
			"Buffer error when writing out ZLib data");
		return -1;

	default:
		return 0;
	}
}

static int lock_file(git_filebuf *file, int flags, mode_t mode)
{
	if (git_path_exists(file->path_lock) == true) {
		if (flags & GIT_FILEBUF_FORCE)
			p_unlink(file->path_lock);
		else {
			giterr_clear(); /* actual OS error code just confuses */
			giterr_set(GITERR_OS,
				"Failed to lock file '%s' for writing", file->path_lock);
			return GIT_ELOCKED;
		}
	}

	/* create path to the file buffer is required */
	if (flags & GIT_FILEBUF_FORCE) {
		/* XXX: Should dirmode here be configurable? Or is 0777 always fine? */
		file->fd = git_futils_creat_locked_withpath(file->path_lock, 0777, mode);
	} else {
		file->fd = git_futils_creat_locked(file->path_lock, mode);
	}

	if (file->fd < 0)
		return file->fd;

	file->fd_is_open = true;

	if ((flags & GIT_FILEBUF_APPEND) && git_path_exists(file->path_original) == true) {
		git_file source;
		char buffer[FILEIO_BUFSIZE];
		ssize_t read_bytes;

		source = p_open(file->path_original, O_RDONLY);
		if (source < 0) {
			giterr_set(GITERR_OS,
				"Failed to open file '%s' for reading",
				file->path_original);
			return -1;
		}

		while ((read_bytes = p_read(source, buffer, sizeof(buffer))) > 0) {
			p_write(file->fd, buffer, read_bytes);
			if (file->compute_digest)
				git_hash_update(&file->digest, buffer, read_bytes);
		}

		p_close(source);

		if (read_bytes < 0) {
			giterr_set(GITERR_OS, "Failed to read file '%s'", file->path_original);
			return -1;
		}
	}

	return 0;
}

void git_filebuf_cleanup(git_filebuf *file)
{
	if (file->fd_is_open && file->fd >= 0)
		p_close(file->fd);

	if (file->created_lock && !file->did_rename && file->path_lock && git_path_exists(file->path_lock))
		p_unlink(file->path_lock);

	if (file->compute_digest) {
		git_hash_ctx_cleanup(&file->digest);
		file->compute_digest = 0;
	}

	if (file->buffer)
		git__free(file->buffer);

	/* use the presence of z_buf to decide if we need to deflateEnd */
	if (file->z_buf) {
		git__free(file->z_buf);
		deflateEnd(&file->zs);
	}

	if (file->path_original)
		git__free(file->path_original);
	if (file->path_lock)
		git__free(file->path_lock);

	memset(file, 0x0, sizeof(git_filebuf));
	file->fd = -1;
}

GIT_INLINE(int) flush_buffer(git_filebuf *file)
{
	int result = file->write(file, file->buffer, file->buf_pos);
	file->buf_pos = 0;
	return result;
}

int git_filebuf_flush(git_filebuf *file)
{
	return flush_buffer(file);
}

static int write_normal(git_filebuf *file, void *source, size_t len)
{
	if (len > 0) {
		if (p_write(file->fd, (void *)source, len) < 0) {
			file->last_error = BUFERR_WRITE;
			return -1;
		}

		if (file->compute_digest)
			git_hash_update(&file->digest, source, len);
	}

	return 0;
}

static int write_deflate(git_filebuf *file, void *source, size_t len)
{
	z_stream *zs = &file->zs;

	if (len > 0 || file->flush_mode == Z_FINISH) {
		zs->next_in = source;
		zs->avail_in = (uInt)len;

		do {
			size_t have;

			zs->next_out = file->z_buf;
			zs->avail_out = (uInt)file->buf_size;

			if (deflate(zs, file->flush_mode) == Z_STREAM_ERROR) {
				file->last_error = BUFERR_ZLIB;
				return -1;
			}

			have = file->buf_size - (size_t)zs->avail_out;

			if (p_write(file->fd, file->z_buf, have) < 0) {
				file->last_error = BUFERR_WRITE;
				return -1;
			}

		} while (zs->avail_out == 0);

		assert(zs->avail_in == 0);

		if (file->compute_digest)
			git_hash_update(&file->digest, source, len);
	}

	return 0;
}

#define MAX_SYMLINK_DEPTH 5

static int resolve_symlink(git_buf *out, const char *path)
{
	int i, error, root;
	ssize_t ret;
	struct stat st;
	git_buf curpath = GIT_BUF_INIT, target = GIT_BUF_INIT;

	if ((error = git_buf_grow(&target, GIT_PATH_MAX + 1)) < 0 ||
	    (error = git_buf_puts(&curpath, path)) < 0)
		return error;

	for (i = 0; i < MAX_SYMLINK_DEPTH; i++) {
		error = p_lstat(curpath.ptr, &st);
		if (error < 0 && errno == ENOENT) {
			error = git_buf_puts(out, curpath.ptr);
			goto cleanup;
		}

		if (error < 0) {
			giterr_set(GITERR_OS, "failed to stat '%s'", curpath.ptr);
			error = -1;
			goto cleanup;
		}

		if (!S_ISLNK(st.st_mode)) {
			error = git_buf_puts(out, curpath.ptr);
			goto cleanup;
		}

		ret = p_readlink(curpath.ptr, target.ptr, GIT_PATH_MAX);
		if (ret < 0) {
			giterr_set(GITERR_OS, "failed to read symlink '%s'", curpath.ptr);
			error = -1;
			goto cleanup;
		}

		if (ret == GIT_PATH_MAX) {
			giterr_set(GITERR_INVALID, "symlink target too long");
			error = -1;
			goto cleanup;
		}

		/* readlink(2) won't NUL-terminate for us */
		target.ptr[ret] = '\0';
		target.size = ret;

		root = git_path_root(target.ptr);
		if (root >= 0) {
			if ((error = git_buf_puts(&curpath, target.ptr)) < 0)
				goto cleanup;
		} else {
			git_buf dir = GIT_BUF_INIT;

			if ((error = git_path_dirname_r(&dir, curpath.ptr)) < 0)
				goto cleanup;

			git_buf_swap(&curpath, &dir);
			git_buf_free(&dir);

			if ((error = git_path_apply_relative(&curpath, target.ptr)) < 0)
				goto cleanup;
		}
	}

	giterr_set(GITERR_INVALID, "maximum symlink depth reached");
	error = -1;

cleanup:
	git_buf_free(&curpath);
	git_buf_free(&target);
	return error;
}

int git_filebuf_open(git_filebuf *file, const char *path, int flags, mode_t mode)
{
	int compression, error = -1;
	size_t path_len, alloc_len;

	/* opening an already open buffer is a programming error;
	 * assert that this never happens instead of returning
	 * an error code */
	assert(file && path && file->buffer == NULL);

	memset(file, 0x0, sizeof(git_filebuf));

	if (flags & GIT_FILEBUF_DO_NOT_BUFFER)
		file->do_not_buffer = true;

	file->buf_size = WRITE_BUFFER_SIZE;
	file->buf_pos = 0;
	file->fd = -1;
	file->last_error = BUFERR_OK;

	/* Allocate the main cache buffer */
	if (!file->do_not_buffer) {
		file->buffer = git__malloc(file->buf_size);
		GITERR_CHECK_ALLOC(file->buffer);
	}

	/* If we are hashing on-write, allocate a new hash context */
	if (flags & GIT_FILEBUF_HASH_CONTENTS) {
		file->compute_digest = 1;

		if (git_hash_ctx_init(&file->digest) < 0)
			goto cleanup;
	}

	compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT;

	/* If we are deflating on-write, */
	if (compression != 0) {
		/* Initialize the ZLib stream */
		if (deflateInit(&file->zs, compression) != Z_OK) {
			giterr_set(GITERR_ZLIB, "Failed to initialize zlib");
			goto cleanup;
		}

		/* Allocate the Zlib cache buffer */
		file->z_buf = git__malloc(file->buf_size);
		GITERR_CHECK_ALLOC(file->z_buf);

		/* Never flush */
		file->flush_mode = Z_NO_FLUSH;
		file->write = &write_deflate;
	} else {
		file->write = &write_normal;
	}

	/* If we are writing to a temp file */
	if (flags & GIT_FILEBUF_TEMPORARY) {
		git_buf tmp_path = GIT_BUF_INIT;

		/* Open the file as temporary for locking */
		file->fd = git_futils_mktmp(&tmp_path, path, mode);

		if (file->fd < 0) {
			git_buf_free(&tmp_path);
			goto cleanup;
		}
		file->fd_is_open = true;
		file->created_lock = true;

		/* No original path */
		file->path_original = NULL;
		file->path_lock = git_buf_detach(&tmp_path);
		GITERR_CHECK_ALLOC(file->path_lock);
	} else {
		git_buf resolved_path = GIT_BUF_INIT;

		if ((error = resolve_symlink(&resolved_path, path)) < 0)
			goto cleanup;

		/* Save the original path of the file */
		path_len = resolved_path.size;
		file->path_original = git_buf_detach(&resolved_path);

		/* create the locking path by appending ".lock" to the original */
		GITERR_CHECK_ALLOC_ADD(&alloc_len, path_len, GIT_FILELOCK_EXTLENGTH);
		file->path_lock = git__malloc(alloc_len);
		GITERR_CHECK_ALLOC(file->path_lock);

		memcpy(file->path_lock, file->path_original, path_len);
		memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);

		if (git_path_isdir(file->path_original)) {
			giterr_set(GITERR_FILESYSTEM, "path '%s' is a directory", file->path_original);
			error = GIT_EDIRECTORY;
			goto cleanup;
		}

		/* open the file for locking */
		if ((error = lock_file(file, flags, mode)) < 0)
			goto cleanup;

		file->created_lock = true;
	}

	return 0;

cleanup:
	git_filebuf_cleanup(file);
	return error;
}

int git_filebuf_hash(git_oid *oid, git_filebuf *file)
{
	assert(oid && file && file->compute_digest);

	flush_buffer(file);

	if (verify_last_error(file) < 0)
		return -1;

	git_hash_final(oid, &file->digest);
	git_hash_ctx_cleanup(&file->digest);
	file->compute_digest = 0;

	return 0;
}

int git_filebuf_commit_at(git_filebuf *file, const char *path)
{
	git__free(file->path_original);
	file->path_original = git__strdup(path);
	GITERR_CHECK_ALLOC(file->path_original);

	return git_filebuf_commit(file);
}

int git_filebuf_commit(git_filebuf *file)
{
	/* temporary files cannot be committed */
	assert(file && file->path_original);

	file->flush_mode = Z_FINISH;
	flush_buffer(file);

	if (verify_last_error(file) < 0)
		goto on_error;

	file->fd_is_open = false;

	if (p_close(file->fd) < 0) {
		giterr_set(GITERR_OS, "Failed to close file at '%s'", file->path_lock);
		goto on_error;
	}

	file->fd = -1;

	if (p_rename(file->path_lock, file->path_original) < 0) {
		giterr_set(GITERR_OS, "Failed to rename lockfile to '%s'", file->path_original);
		goto on_error;
	}

	file->did_rename = true;

	git_filebuf_cleanup(file);
	return 0;

on_error:
	git_filebuf_cleanup(file);
	return -1;
}

GIT_INLINE(void) add_to_cache(git_filebuf *file, const void *buf, size_t len)
{
	memcpy(file->buffer + file->buf_pos, buf, len);
	file->buf_pos += len;
}

int git_filebuf_write(git_filebuf *file, const void *buff, size_t len)
{
	const unsigned char *buf = buff;

	ENSURE_BUF_OK(file);

	if (file->do_not_buffer)
		return file->write(file, (void *)buff, len);

	for (;;) {
		size_t space_left = file->buf_size - file->buf_pos;

		/* cache if it's small */
		if (space_left > len) {
			add_to_cache(file, buf, len);
			return 0;
		}

		add_to_cache(file, buf, space_left);
		if (flush_buffer(file) < 0)
			return -1;

		len -= space_left;
		buf += space_left;
	}
}

int git_filebuf_reserve(git_filebuf *file, void **buffer, size_t len)
{
	size_t space_left = file->buf_size - file->buf_pos;

	*buffer = NULL;

	ENSURE_BUF_OK(file);

	if (len > file->buf_size) {
		file->last_error = BUFERR_MEM;
		return -1;
	}

	if (space_left <= len) {
		if (flush_buffer(file) < 0)
			return -1;
	}

	*buffer = (file->buffer + file->buf_pos);
	file->buf_pos += len;

	return 0;
}

int git_filebuf_printf(git_filebuf *file, const char *format, ...)
{
	va_list arglist;
	size_t space_left, len, alloclen;
	int written, res;
	char *tmp_buffer;

	ENSURE_BUF_OK(file);

	space_left = file->buf_size - file->buf_pos;

	do {
		va_start(arglist, format);
		written = p_vsnprintf((char *)file->buffer + file->buf_pos, space_left, format, arglist);
		va_end(arglist);

		if (written < 0) {
			file->last_error = BUFERR_MEM;
			return -1;
		}

		len = written;
		if (len + 1 <= space_left) {
			file->buf_pos += len;
			return 0;
		}

		if (flush_buffer(file) < 0)
			return -1;

		space_left = file->buf_size - file->buf_pos;

	} while (len + 1 <= space_left);

	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, len, 1) ||
		!(tmp_buffer = git__malloc(alloclen))) {
		file->last_error = BUFERR_MEM;
		return -1;
	}

	va_start(arglist, format);
	written = p_vsnprintf(tmp_buffer, len + 1, format, arglist);
	va_end(arglist);

	if (written < 0) {
		git__free(tmp_buffer);
		file->last_error = BUFERR_MEM;
		return -1;
	}

	res = git_filebuf_write(file, tmp_buffer, len);
	git__free(tmp_buffer);

	return res;
}

int git_filebuf_stats(time_t *mtime, size_t *size, git_filebuf *file)
{
	int res;
	struct stat st;

	if (file->fd_is_open)
		res = p_fstat(file->fd, &st);
	else
		res = p_stat(file->path_original, &st);

	if (res < 0) {
		giterr_set(GITERR_OS, "Could not get stat info for '%s'",
			file->path_original);
		return res;
	}

	if (mtime)
		*mtime = st.st_mtime;
	if (size)
		*size = (size_t)st.st_size;

	return 0;
}
