/*
 * Copyright (C) 2015 The ChromiumOS Authors.  All rights reserved.
 *                 written by Daisuke Nojiri <dnojiri@chromium.org>
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

#include "archive.h"
#include <endian.h>
#include <errno.h>
#include <libgen.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static struct directory *archive;

static void usage(void)
{
	printf("Name:\n");
	printf("	archive - concatenate files and create an archive\n");
	printf("Usage:\n");
	printf("	archive archive_name create file0 file1 ...\n");
}

static int get_file_size(const char *file)
{
	FILE *fp = fopen(file, "rb");
	int size;

	if (!fp) {
		fprintf(stderr, "Error: failed to open %s\n", file);
		return -1;
	}
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fclose(fp);
	if (size < 0) {
		fprintf(stderr, "Error: failed to get file size\n");
		return -1;
	}

	return size;
}

static int set_file_name(const char *path, struct dentry *dest)
{
	struct dentry *entry;
	char *name, *copy;
	int i;

	copy = strdup(path);
	name = basename(copy);

	/* check name length */
	if (strlen(name) > NAME_LENGTH) {
		fprintf(stderr, "Error: file name '%s' exceeds %d chars\n",
			name, NAME_LENGTH);
		free(copy);
		return -1;
	}

	/* check if there is a duplicate name */
	entry = get_first_dentry(archive);
	for (i = 0; i < archive->count && &entry[i] != dest; i++) {
		if (!strncmp(entry[i].name, name, NAME_LENGTH)) {
			fprintf(stderr, "Error: duplicate name '%s'\n", name);
			free(copy);
			return -1;
		}
	}

	/* copy the name to the entry */
	strncpy(dest->name, name, NAME_LENGTH);
	free(copy);

	return 0;
}

/*
 * Add a file to the archive in RAM
 *
 * path: path to the file to be added
 * entry: pointer to struct dentry where file header is created
 * offset: offset of the file contents from the archive header
 *
 * return: 0 on success or -1 on error
 */
static int add_file(const char *path, struct dentry *entry, uint32_t offset)
{
	FILE *fp;
	int size;

	if (!path || !*path || !entry) {
		fprintf(stderr, "Error: invalid path or entry\n");
		return -1;
	}

	size = get_file_size(path);
	if (size < 0)
		return -1;
	if (offset + size > archive->size) {
		fprintf(stderr, "Error: invalid offset or size\n");
		return -1;
	}

	fp = fopen(path, "rb");
	if (!fp) {
		fprintf(stderr, "Error: failed to open %s (%d: %s)\n",
			path, errno, strerror(errno));
		return -1;
	}
	if (fread((char *)archive + offset, sizeof(char), size, fp) != size) {
		fprintf(stderr, "Error: failed to read %s\n", path);
		fclose(fp);
		return -1;
	}
	fclose(fp);

	/* set file name*/
	if (set_file_name(path, entry))
		return -1;

	entry->offset = offset;
	entry->size = size;

	return 0;
}

/*
 * Allocate memory for archive
 *
 * count: number of files to add
 * files: pointer to the array of file names
 *
 * return: 0 on success or -1 on error
 */
static int setup_archive(int count, const char **files)
{
	uint32_t size;
	int i, s;

	size = sizeof(*archive);
	for (i = 0; i < count; i++) {
		s = get_file_size(files[i]);
		if (s < 0)
			return -1;
		size += sizeof(struct dentry);
		size += s;
	}

	archive = calloc(size, 1);
	if (!archive) {
		fprintf(stderr, "Error: failed to allocate memory\n");
		return -1;
	}

	/* install magic string */
	memcpy(archive->magic, CBAR_MAGIC, sizeof(archive->magic));
	archive->version = VERSION;
	archive->size = size;
	archive->count = count;

	printf("Set up archive: size=%d count=%d\n", size, count);

	return 0;
}

/*
 * Store files in archive
 */
static int archive_files(const char **files)
{
	struct dentry *entry;
	uint32_t offset;
	int i;

	entry = get_first_dentry(archive);
	offset = get_first_offset(archive);
	for (i = 0; i < archive->count; i++) {
		if (add_file(files[i], entry, offset))
			return -1;
		offset += entry->size;
		entry++;
	}

	return 0;
}

static void convert_endian(void)
{
	struct dentry *entry;
	int i;

	entry = get_first_dentry(archive);
	for (i = 0; i < archive->count; i++) {
		entry[i].offset = htole32(entry[i].offset);
		entry[i].size = htole32(entry[i].size);
	}

	archive->version = htole32(archive->version);
	archive->size = htole32(archive->size);
	archive->count = htole32(archive->count);
}

/*
 * Write archive to file
 */
static int output_archive(const char *path)
{
	FILE *fp;

	convert_endian();

	fp = fopen(path, "wb");
	if (!fp) {
		fprintf(stderr, "Error: failed to open %s\n", path);
		fclose(fp);
		return -1;
	}
	if (fwrite(archive, sizeof(char), archive->size, fp) != archive->size) {
		fprintf(stderr, "Error: failed to write to %s\n", path);
		fclose(fp);
		return -1;
	}
	fclose(fp);
	printf("Wrote archive to %s\n", path);

	return 0;
}

static int cmd_create(const char *archive_path, int count, const char **files)
{
	if (count < 1 || !files) {
		fprintf(stderr, "Error: no input files specified\n");
		return -1;
	}

	if (setup_archive(count, files))
		return -1;

	if (archive_files(files))
		return -1;

	if (output_archive(archive_path))
		return -1;

	return 0;
}

int main(int argc, const char *argv[])
{
	const char *command;

	if (argc < 3) {
		fprintf(stderr, "Error: invalid number of arguments\n");
		usage();
		return -1;
	}

	command = argv[2];

	/* branch by command name */
	if (!strncmp(command, "create", sizeof("create"))) {
		if (cmd_create(argv[1], argc - 3, &argv[3]))
			return -1;
	} else {
		fprintf(stderr, "Error: invalid command: %s\n", command);
		return -1;
	}

	return 0;
}
