/*
 * Copyright (C) 2010 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 _FILE_OFFSET_BITS 64
#define _LARGEFILE64_SOURCE 1

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <libgen.h>
#include <unistd.h>

#include <sparse/sparse.h>

#include "ext4_utils.h"
#include "make_ext4fs.h"
#include "allocate.h"

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

#ifndef USE_MINGW /* O_BINARY is windows-specific flag */
#define O_BINARY 0
#endif

extern struct fs_info info;

static int verbose = 0;

static void usage(char *path)
{
	fprintf(stderr, "%s [ options ] <image or block device> <output image>\n", path);
	fprintf(stderr, "\n");
	fprintf(stderr, "  -c include CRC block\n");
	fprintf(stderr, "  -v verbose output\n");
	fprintf(stderr, "  -z gzip output\n");
	fprintf(stderr, "  -S don't use sparse output format\n");
}

static int read_ext(int fd)
{
	off64_t ret;
	struct ext4_super_block sb;
	unsigned int i;

	ret = lseek64(fd, 1024, SEEK_SET);
	if (ret < 0)
		critical_error_errno("failed to seek to superblock");

	ret = read(fd, &sb, sizeof(sb));
	if (ret < 0)
		critical_error_errno("failed to read superblock");
	if (ret != sizeof(sb))
		critical_error("failed to read all of superblock");

	ext4_parse_sb(&sb);

	ret = lseek64(fd, info.len, SEEK_SET);
	if (ret < 0)
		critical_error_errno("failed to seek to end of input image");

	ret = lseek64(fd, info.block_size * (aux_info.first_data_block + 1), SEEK_SET);
	if (ret < 0)
		critical_error_errno("failed to seek to block group descriptors");

	ret = read(fd, aux_info.bg_desc, info.block_size * aux_info.bg_desc_blocks);
	if (ret < 0)
		critical_error_errno("failed to read block group descriptors");
	if (ret != (int)info.block_size * (int)aux_info.bg_desc_blocks)
		critical_error("failed to read all of block group descriptors");

	if (verbose) {
		printf("Found filesystem with parameters:\n");
		printf("    Size: %llu\n", info.len);
		printf("    Block size: %d\n", info.block_size);
		printf("    Blocks per group: %d\n", info.blocks_per_group);
		printf("    Inodes per group: %d\n", info.inodes_per_group);
		printf("    Inode size: %d\n", info.inode_size);
		printf("    Label: %s\n", info.label);
		printf("    Blocks: %llu\n", aux_info.len_blocks);
		printf("    Block groups: %d\n", aux_info.groups);
		printf("    Reserved block group size: %d\n", info.bg_desc_reserve_blocks);
		printf("    Used %d/%d inodes and %d/%d blocks\n",
				aux_info.sb->s_inodes_count - aux_info.sb->s_free_inodes_count,
				aux_info.sb->s_inodes_count,
				aux_info.sb->s_blocks_count_lo - aux_info.sb->s_free_blocks_count_lo,
				aux_info.sb->s_blocks_count_lo);
	}

	return 0;
}

static int bitmap_get_bit(u8 *bitmap, u32 bit)
{
	if (bitmap[bit / 8] & 1 << (bit % 8))
		return 1;

	return 0;
}

static int build_sparse_ext(int fd, const char *filename)
{
	unsigned int i;
	unsigned int block;
	int start_contiguous_block;
	u8 *block_bitmap;
	off64_t ret;

	block_bitmap = malloc(info.block_size);
	if (!block_bitmap)
		critical_error("failed to allocate block bitmap");

	if (aux_info.first_data_block > 0)
		sparse_file_add_file(info.sparse_file, filename, 0,
				info.block_size * aux_info.first_data_block, 0);

	for (i = 0; i < aux_info.groups; i++) {
		u32 first_block = aux_info.first_data_block + i * info.blocks_per_group;
		u32 last_block = min(info.blocks_per_group, aux_info.len_blocks - first_block);

		ret = lseek64(fd, (u64)info.block_size * aux_info.bg_desc[i].bg_block_bitmap,
				SEEK_SET);
		if (ret < 0)
			critical_error_errno("failed to seek to block group bitmap %d", i);

		ret = read(fd, block_bitmap, info.block_size);
		if (ret < 0)
			critical_error_errno("failed to read block group bitmap %d", i);
		if (ret != (int)info.block_size)
			critical_error("failed to read all of block group bitmap %d", i);

		start_contiguous_block = -1;
		for (block = 0; block < last_block; block++) {
			if (start_contiguous_block >= 0) {
				if (!bitmap_get_bit(block_bitmap, block)) {
					u32 start_block = first_block + start_contiguous_block;
					u32 len_blocks = block - start_contiguous_block;

					sparse_file_add_file(info.sparse_file, filename,
							(u64)info.block_size * start_block,
							info.block_size * len_blocks, start_block);
					start_contiguous_block = -1;
				}
			} else {
				if (bitmap_get_bit(block_bitmap, block))
					start_contiguous_block = block;
			}
		}

		if (start_contiguous_block >= 0) {
			u32 start_block = first_block + start_contiguous_block;
			u32 len_blocks = last_block - start_contiguous_block;
			sparse_file_add_file(info.sparse_file, filename,
					(u64)info.block_size * start_block,
					info.block_size * len_blocks, start_block);
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	int opt;
	const char *in = NULL;
	const char *out = NULL;
	int gzip = 0;
	int sparse = 1;
	int infd, outfd;
	int crc = 0;

	while ((opt = getopt(argc, argv, "cvzS")) != -1) {
		switch (opt) {
		case 'c':
			crc = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'z':
			gzip = 1;
			break;
		case 'S':
			sparse = 0;
			break;
		}
	}

	if (optind >= argc) {
		fprintf(stderr, "Expected image or block device after options\n");
		usage(argv[0]);
		exit(EXIT_FAILURE);
	}

	in = argv[optind++];

	if (optind >= argc) {
		fprintf(stderr, "Expected output image after input image\n");
		usage(argv[0]);
		exit(EXIT_FAILURE);
	}

	out = argv[optind++];

	if (optind < argc) {
		fprintf(stderr, "Unexpected argument: %s\n", argv[optind]);
		usage(argv[0]);
		exit(EXIT_FAILURE);
	}

	infd = open(in, O_RDONLY);

	if (infd < 0)
		critical_error_errno("failed to open input image");

	read_ext(infd);

	info.sparse_file = sparse_file_new(info.block_size, info.len);

	build_sparse_ext(infd, in);

	close(infd);

	if (strcmp(out, "-")) {
		outfd = open(out, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
		if (outfd < 0) {
			error_errno("open");
			return EXIT_FAILURE;
		}
	} else {
		outfd = STDOUT_FILENO;
	}

	write_ext4_image(outfd, gzip, sparse, crc);
	close(outfd);

	sparse_file_destroy(info.sparse_file);

	return 0;
}
