/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE64_SOURCE 1

#include <fcntl.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sparse/sparse.h>

#include "defs.h"
#include "output_file.h"
#include "sparse_crc32.h"
#include "sparse_file.h"
#include "sparse_format.h"

#if defined(__APPLE__) && defined(__MACH__)
#define lseek64 lseek
#define off64_t off_t
#endif

#define SPARSE_HEADER_MAJOR_VER 1
#define SPARSE_HEADER_LEN       (sizeof(sparse_header_t))
#define CHUNK_HEADER_LEN (sizeof(chunk_header_t))

#define COPY_BUF_SIZE (1024U*1024U)
static char *copybuf;

#define min(a, b) \
	({ typeof(a) _a = (a); typeof(b) _b = (b); (_a < _b) ? _a : _b; })

static void verbose_error(bool verbose, int err, const char *fmt, ...)
{
	char *s = "";
	char *at = "";
	if (fmt) {
		va_list argp;
		int size;

		va_start(argp, fmt);
		size = vsnprintf(NULL, 0, fmt, argp);
		va_end(argp);

		if (size < 0) {
			return;
		}

		at = malloc(size + 1);
		if (at == NULL) {
			return;
		}

		va_start(argp, fmt);
		vsnprintf(at, size, fmt, argp);
		va_end(argp);
		at[size] = 0;
		s = " at ";
	}
	if (verbose) {
#ifndef USE_MINGW
		if (err == -EOVERFLOW) {
			sparse_print_verbose("EOF while reading file%s%s\n", s, at);
		} else
#endif
		if (err == -EINVAL) {
			sparse_print_verbose("Invalid sparse file format%s%s\n", s, at);
		} else if (err == -ENOMEM) {
			sparse_print_verbose("Failed allocation while reading file%s%s\n",
					s, at);
		} else {
			sparse_print_verbose("Unknown error %d%s%s\n", err, s, at);
		}
	}
	if (fmt) {
		free(at);
	}
}

static int process_raw_chunk(struct sparse_file *s, unsigned int chunk_size,
		int fd, int64_t offset, unsigned int blocks, unsigned int block,
		uint32_t *crc32)
{
	int ret;
	int chunk;
	unsigned int len = blocks * s->block_size;

	if (chunk_size % s->block_size != 0) {
		return -EINVAL;
	}

	if (chunk_size / s->block_size != blocks) {
		return -EINVAL;
	}

	ret = sparse_file_add_fd(s, fd, offset, len, block);
	if (ret < 0) {
		return ret;
	}

	if (crc32) {
		while (len) {
			chunk = min(len, COPY_BUF_SIZE);
			ret = read_all(fd, copybuf, chunk);
			if (ret < 0) {
				return ret;
			}
			*crc32 = sparse_crc32(*crc32, copybuf, chunk);
			len -= chunk;
		}
	} else {
		lseek64(fd, len, SEEK_CUR);
	}

	return 0;
}

static int process_fill_chunk(struct sparse_file *s, unsigned int chunk_size,
		int fd, unsigned int blocks, unsigned int block, uint32_t *crc32)
{
	int ret;
	int chunk;
	int64_t len = (int64_t)blocks * s->block_size;
	uint32_t fill_val;
	uint32_t *fillbuf;
	unsigned int i;

	if (chunk_size != sizeof(fill_val)) {
		return -EINVAL;
	}

	ret = read_all(fd, &fill_val, sizeof(fill_val));
	if (ret < 0) {
		return ret;
	}

	ret = sparse_file_add_fill(s, fill_val, len, block);
	if (ret < 0) {
		return ret;
	}

	if (crc32) {
		/* Fill copy_buf with the fill value */
		fillbuf = (uint32_t *)copybuf;
		for (i = 0; i < (COPY_BUF_SIZE / sizeof(fill_val)); i++) {
			fillbuf[i] = fill_val;
		}

		while (len) {
			chunk = min(len, COPY_BUF_SIZE);
			*crc32 = sparse_crc32(*crc32, copybuf, chunk);
			len -= chunk;
		}
	}

	return 0;
}

static int process_skip_chunk(struct sparse_file *s, unsigned int chunk_size,
		int fd __unused, unsigned int blocks,
		unsigned int block __unused, uint32_t *crc32)
{
	if (chunk_size != 0) {
		return -EINVAL;
	}

	if (crc32) {
	        int64_t len = (int64_t)blocks * s->block_size;
		memset(copybuf, 0, COPY_BUF_SIZE);

		while (len) {
			int chunk = min(len, COPY_BUF_SIZE);
			*crc32 = sparse_crc32(*crc32, copybuf, chunk);
			len -= chunk;
		}
	}

	return 0;
}

static int process_crc32_chunk(int fd, unsigned int chunk_size, uint32_t crc32)
{
	uint32_t file_crc32;
	int ret;

	if (chunk_size != sizeof(file_crc32)) {
		return -EINVAL;
	}

	ret = read_all(fd, &file_crc32, sizeof(file_crc32));
	if (ret < 0) {
		return ret;
	}

	if (file_crc32 != crc32) {
		return -EINVAL;
	}

	return 0;
}

static int process_chunk(struct sparse_file *s, int fd, off64_t offset,
		unsigned int chunk_hdr_sz, chunk_header_t *chunk_header,
		unsigned int cur_block, uint32_t *crc_ptr)
{
	int ret;
	unsigned int chunk_data_size;

	chunk_data_size = chunk_header->total_sz - chunk_hdr_sz;

	switch (chunk_header->chunk_type) {
		case CHUNK_TYPE_RAW:
			ret = process_raw_chunk(s, chunk_data_size, fd, offset,
					chunk_header->chunk_sz, cur_block, crc_ptr);
			if (ret < 0) {
				verbose_error(s->verbose, ret, "data block at %lld", offset);
				return ret;
			}
			return chunk_header->chunk_sz;
		case CHUNK_TYPE_FILL:
			ret = process_fill_chunk(s, chunk_data_size, fd,
					chunk_header->chunk_sz, cur_block, crc_ptr);
			if (ret < 0) {
				verbose_error(s->verbose, ret, "fill block at %lld", offset);
				return ret;
			}
			return chunk_header->chunk_sz;
		case CHUNK_TYPE_DONT_CARE:
			ret = process_skip_chunk(s, chunk_data_size, fd,
					chunk_header->chunk_sz, cur_block, crc_ptr);
			if (chunk_data_size != 0) {
				if (ret < 0) {
					verbose_error(s->verbose, ret, "skip block at %lld", offset);
					return ret;
				}
			}
			return chunk_header->chunk_sz;
		case CHUNK_TYPE_CRC32:
			ret = process_crc32_chunk(fd, chunk_data_size, *crc_ptr);
			if (ret < 0) {
				verbose_error(s->verbose, -EINVAL, "crc block at %lld",
						offset);
				return ret;
			}
			return 0;
		default:
			verbose_error(s->verbose, -EINVAL, "unknown block %04X at %lld",
					chunk_header->chunk_type, offset);
	}

	return 0;
}

static int sparse_file_read_sparse(struct sparse_file *s, int fd, bool crc)
{
	int ret;
	unsigned int i;
	sparse_header_t sparse_header;
	chunk_header_t chunk_header;
	uint32_t crc32 = 0;
	uint32_t *crc_ptr = 0;
	unsigned int cur_block = 0;
	off64_t offset;

	if (!copybuf) {
		copybuf = malloc(COPY_BUF_SIZE);
	}

	if (!copybuf) {
		return -ENOMEM;
	}

	if (crc) {
		crc_ptr = &crc32;
	}

	ret = read_all(fd, &sparse_header, sizeof(sparse_header));
	if (ret < 0) {
		return ret;
	}

	if (sparse_header.magic != SPARSE_HEADER_MAGIC) {
		return -EINVAL;
	}

	if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) {
		return -EINVAL;
	}

	if (sparse_header.file_hdr_sz < SPARSE_HEADER_LEN) {
		return -EINVAL;
	}

	if (sparse_header.chunk_hdr_sz < sizeof(chunk_header)) {
		return -EINVAL;
	}

	if (sparse_header.file_hdr_sz > SPARSE_HEADER_LEN) {
		/* Skip the remaining bytes in a header that is longer than
		 * we expected.
		 */
		lseek64(fd, sparse_header.file_hdr_sz - SPARSE_HEADER_LEN, SEEK_CUR);
	}

	for (i = 0; i < sparse_header.total_chunks; i++) {
		ret = read_all(fd, &chunk_header, sizeof(chunk_header));
		if (ret < 0) {
			return ret;
		}

		if (sparse_header.chunk_hdr_sz > CHUNK_HEADER_LEN) {
			/* Skip the remaining bytes in a header that is longer than
			 * we expected.
			 */
			lseek64(fd, sparse_header.chunk_hdr_sz - CHUNK_HEADER_LEN, SEEK_CUR);
		}

		offset = lseek64(fd, 0, SEEK_CUR);

		ret = process_chunk(s, fd, offset, sparse_header.chunk_hdr_sz, &chunk_header,
				cur_block, crc_ptr);
		if (ret < 0) {
			return ret;
		}

		cur_block += ret;
	}

	if (sparse_header.total_blks != cur_block) {
		return -EINVAL;
	}

	return 0;
}

static int sparse_file_read_normal(struct sparse_file *s, int fd)
{
	int ret;
	uint32_t *buf = malloc(s->block_size);
	unsigned int block = 0;
	int64_t remain = s->len;
	int64_t offset = 0;
	unsigned int to_read;
	unsigned int i;
	bool sparse_block;

	if (!buf) {
		return -ENOMEM;
	}

	while (remain > 0) {
		to_read = min(remain, s->block_size);
		ret = read_all(fd, buf, to_read);
		if (ret < 0) {
			error("failed to read sparse file");
			return ret;
		}

		if (to_read == s->block_size) {
			sparse_block = true;
			for (i = 1; i < s->block_size / sizeof(uint32_t); i++) {
				if (buf[0] != buf[i]) {
					sparse_block = false;
					break;
				}
			}
		} else {
			sparse_block = false;
		}

		if (sparse_block) {
			/* TODO: add flag to use skip instead of fill for buf[0] == 0 */
			sparse_file_add_fill(s, buf[0], to_read, block);
		} else {
			sparse_file_add_fd(s, fd, offset, to_read, block);
		}

		remain -= to_read;
		offset += to_read;
		block++;
	}

	return 0;
}

int sparse_file_read(struct sparse_file *s, int fd, bool sparse, bool crc)
{
	if (crc && !sparse) {
		return -EINVAL;
	}

	if (sparse) {
		return sparse_file_read_sparse(s, fd, crc);
	} else {
		return sparse_file_read_normal(s, fd);
	}
}

struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc)
{
	int ret;
	sparse_header_t sparse_header;
	int64_t len;
	struct sparse_file *s;

	ret = read_all(fd, &sparse_header, sizeof(sparse_header));
	if (ret < 0) {
		verbose_error(verbose, ret, "header");
		return NULL;
	}

	if (sparse_header.magic != SPARSE_HEADER_MAGIC) {
		verbose_error(verbose, -EINVAL, "header magic");
		return NULL;
	}

	if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) {
		verbose_error(verbose, -EINVAL, "header major version");
		return NULL;
	}

	if (sparse_header.file_hdr_sz < SPARSE_HEADER_LEN) {
		return NULL;
	}

	if (sparse_header.chunk_hdr_sz < sizeof(chunk_header_t)) {
		return NULL;
	}

	len = (int64_t)sparse_header.total_blks * sparse_header.blk_sz;
	s = sparse_file_new(sparse_header.blk_sz, len);
	if (!s) {
		verbose_error(verbose, -EINVAL, NULL);
		return NULL;
	}

	ret = lseek64(fd, 0, SEEK_SET);
	if (ret < 0) {
		verbose_error(verbose, ret, "seeking");
		sparse_file_destroy(s);
		return NULL;
	}

	s->verbose = verbose;

	ret = sparse_file_read(s, fd, true, crc);
	if (ret < 0) {
		sparse_file_destroy(s);
		return NULL;
	}

	return s;
}

struct sparse_file *sparse_file_import_auto(int fd, bool crc, bool verbose)
{
	struct sparse_file *s;
	int64_t len;
	int ret;

	s = sparse_file_import(fd, verbose, crc);
	if (s) {
		return s;
	}

	len = lseek64(fd, 0, SEEK_END);
	if (len < 0) {
		return NULL;
	}

	lseek64(fd, 0, SEEK_SET);

	s = sparse_file_new(4096, len);
	if (!s) {
		return NULL;
	}

	ret = sparse_file_read_normal(s, fd);
	if (ret < 0) {
		sparse_file_destroy(s);
		return NULL;
	}

	return s;
}
