/*-
 * Copyright (c) 2012 Michihiro NAKAJIMA
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "bsdtar_platform.h"
__FBSDID("$FreeBSD$");

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include "bsdtar.h"
#include "err.h"

struct creation_set {
	char		 *create_format;
	struct filter_set {
		int	  program;	/* Set 1 if filter is a program name */
		char	 *filter_name;
	}		 *filters;
	int		  filter_count;
};

struct suffix_code_t {
	const char *suffix;
	const char *form;
};

static const char *
get_suffix_code(const struct suffix_code_t *tbl, const char *suffix)
{
	int i;

	if (suffix == NULL)
		return (NULL);
	for (i = 0; tbl[i].suffix != NULL; i++) {
		if (strcmp(tbl[i].suffix, suffix) == 0)
			return (tbl[i].form);
	}
	return (NULL);
}

static const char *
get_filter_code(const char *suffix)
{
	/* A pair of suffix and compression/filter. */
	static const struct suffix_code_t filters[] = {
		{ ".Z",		"compress" },
		{ ".bz2",	"bzip2" },
		{ ".gz",	"gzip" },
		{ ".grz",	"grzip" },
		{ ".lrz",	"lrzip" },
		{ ".lz",	"lzip" },
		{ ".lzo",	"lzop" },
		{ ".lzma",	"lzma" },
		{ ".uu",	"uuencode" },
		{ ".xz",	"xz" },
		{ NULL,		NULL }
	};
	
	return get_suffix_code(filters, suffix);
}

static const char *
get_format_code(const char *suffix)
{
	/* A pair of suffix and format. */
	static const struct suffix_code_t formats[] = {
		{ ".7z",	"7zip" },
		{ ".ar",	"arbsd" },
		{ ".cpio",	"cpio" },
		{ ".iso",	"iso9960" },
		{ ".mtree",	"mtree" },
		{ ".shar",	"shar" },
		{ ".tar",	"paxr" },
		{ ".xar",	"xar" },
		{ ".zip",	"zip" },
		{ NULL,		NULL }
	};

	return get_suffix_code(formats, suffix);
}

static const char *
decompose_alias(const char *suffix)
{
	static const struct suffix_code_t alias[] = {
		{ ".taz",	".tar.gz" },
		{ ".tgz",	".tar.gz" },
		{ ".tbz",	".tar.bz2" },
		{ ".tbz2",	".tar.bz2" },
		{ ".tz2",	".tar.bz2" },
		{ ".tlz",	".tar.lzma" },
		{ ".txz",	".tar.xz" },
		{ ".tzo",	".tar.lzo" },
		{ ".taZ",	".tar.Z" },
		{ ".tZ",	".tar.Z" },
		{ NULL,		NULL }
	};

	return get_suffix_code(alias, suffix);
}

static void
_cset_add_filter(struct creation_set *cset, int program, const char *filter)
{
	struct filter_set *new_ptr;
	char *new_filter;

	new_ptr = (struct filter_set *)realloc(cset->filters,
	    sizeof(*cset->filters) * (cset->filter_count + 1));
	if (new_ptr == NULL)
		lafe_errc(1, 0, "No memory");
	new_filter = strdup(filter);
	if (new_filter == NULL)
		lafe_errc(1, 0, "No memory");
	cset->filters = new_ptr;
	cset->filters[cset->filter_count].program = program;
	cset->filters[cset->filter_count].filter_name = new_filter;
	cset->filter_count++;
}

void
cset_add_filter(struct creation_set *cset, const char *filter)
{
	_cset_add_filter(cset, 0, filter);
}

void
cset_add_filter_program(struct creation_set *cset, const char *filter)
{
	_cset_add_filter(cset, 1, filter);
}

int
cset_read_support_filter_program(struct creation_set *cset, struct archive *a)
{
	int cnt = 0, i;

	for (i = 0; i < cset->filter_count; i++) {
		if (cset->filters[i].program) {
			archive_read_support_filter_program(a,
			    cset->filters[i].filter_name);
			++cnt;
		}
	}
	return (cnt);
}

int
cset_write_add_filters(struct creation_set *cset, struct archive *a,
    const void **filter_name)
{
	int cnt = 0, i, r;

	for (i = 0; i < cset->filter_count; i++) {
		if (cset->filters[i].program)
			r = archive_write_add_filter_program(a,
				cset->filters[i].filter_name);
		else
			r = archive_write_add_filter_by_name(a,
				cset->filters[i].filter_name);
		if (r < ARCHIVE_WARN) {
			*filter_name = cset->filters[i].filter_name;
			return (r);
		}
		++cnt;
	}
	return (cnt);
}

void
cset_set_format(struct creation_set *cset, const char *format)
{
	char *f;

	f = strdup(format);
	if (f == NULL)
		lafe_errc(1, 0, "No memory");
	free(cset->create_format);
	cset->create_format = f;
}

const char *
cset_get_format(struct creation_set *cset)
{
	return (cset->create_format);
}

static void
_cleanup_filters(struct filter_set *filters, int count)
{
	int i;

	for (i = 0; i < count; i++)
		free(filters[i].filter_name);
	free(filters);
}

/*
 * Clean up a creation set.
 */
void
cset_free(struct creation_set *cset)
{
	_cleanup_filters(cset->filters, cset->filter_count);
	free(cset->create_format);
	free(cset);
}

struct creation_set *
cset_new(void)
{
	return calloc(1, sizeof(struct creation_set));
}

/*
 * Build a creation set by a file name suffix.
 */
int
cset_auto_compress(struct creation_set *cset, const char *filename)
{
	struct filter_set *old_filters;
	char *name, *p;
	const char *code;
	int old_filter_count;

	name = strdup(filename);
	if (name == NULL)
		lafe_errc(1, 0, "No memory");
	/* Save previous filters. */
	old_filters = cset->filters;
	old_filter_count = cset->filter_count;
	cset->filters = NULL;
	cset->filter_count = 0;

	for (;;) {
		/* Get the suffix. */
		p = strrchr(name, '.');
		if (p == NULL)
			break;
		/* Suppose it indicates compression/filter type
		 * such as ".gz". */
		code = get_filter_code(p);
		if (code != NULL) {
			cset_add_filter(cset, code);
			*p = '\0';
			continue;
		}
		/* Suppose it indicates format type such as ".tar". */
		code = get_format_code(p);
		if (code != NULL) {
			cset_set_format(cset, code);
			break;
		}
		/* Suppose it indicates alias such as ".tgz". */
		code = decompose_alias(p);
		if (code == NULL)
			break;
		/* Replace the suffix. */
		*p = '\0';
		name = realloc(name, strlen(name) + strlen(code) + 1);
		if (name == NULL)
			lafe_errc(1, 0, "No memory");
		strcat(name, code);
	}
	free(name);
	if (cset->filters) {
		struct filter_set *v;
		int i, r;

		/* Release previos filters. */
		_cleanup_filters(old_filters, old_filter_count);

		v = malloc(sizeof(*v) * cset->filter_count);
		if (v == NULL)
			lafe_errc(1, 0, "No memory");
		/* Reverse filter sequence. */
		for (i = 0, r = cset->filter_count; r > 0; )
			v[i++] = cset->filters[--r];
		free(cset->filters);
		cset->filters = v;
		return (1);
	} else {
		/* Put previos filters back. */
		cset->filters = old_filters;
		cset->filter_count = old_filter_count;
		return (0);
	}
}
