/*
 * This file is part of the bayou project.
 *
 * Copyright (C) 2008 Advanced Micro Devices, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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 <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <libgen.h>
#include "liblar.h"
#include "pbuilder.h"

void do_lzma_compress(char *in, int in_len, char *out, int *out_len);

int add_bpt_to_lar(struct LAR *lar, struct config *config)
{
	char *buffer;
	int ret, i, len = sizeof(struct bpt_config);
	struct bpt_config *cfg;
	struct LARAttr attr;
	char *ptr;

	for (i = 0; i < config->n_entries; i++) {
		len += sizeof(struct bpt_pentry);

		if (config->entries[i]->type != BPT_TYPE_CHAIN)
			len += ((strlen(config->entries[i]->larname)
				+ 15) & ~0x0F);
	}

	buffer = calloc(len, 1);

	if (buffer == NULL)
		return -1;

	cfg = (struct bpt_config *)buffer;

	cfg->id = BPT_ID;
	cfg->timeout = config->timeout;
	cfg->entries = config->n_entries;

	ptr = buffer + sizeof(struct bpt_config);

	for (i = 0; i < config->n_entries; i++) {
		int nlen = 0;
		struct bpt_pentry *pentry = (struct bpt_pentry *)ptr;

		pentry->index = config->entries[i]->index;
		pentry->parent = config->entries[i]->parent;
		pentry->type = config->entries[i]->type;
		pentry->flags = config->entries[i]->flags;

		strncpy((char *)pentry->title,
			(char *)config->entries[i]->title,
			sizeof(pentry->title));

		if (config->entries[i]->type != BPT_TYPE_CHAIN) {
			nlen = strlen(config->entries[i]->larname);
			nlen = (nlen + 15) & ~0x0F;

			strcpy((char *)(ptr + sizeof(struct bpt_pentry)),
			       config->entries[i]->larname);

			pentry->nlen = nlen;
		}

		ptr += sizeof(struct bpt_pentry);

		if (config->entries[i]->type != BPT_TYPE_CHAIN)
			ptr += nlen;
	}

	LAR_SetAttrs(&attr, "bayou_payload_table", ALGO_NONE);

	ret = LAR_AppendBuffer(lar, (unsigned char *)buffer, len, &attr);
	free(buffer);
	return ret;
}

struct lfile {
	char *file;
	char *larname;
};

int n_lfiles;

int create_lar_from_config(const char *input, const char *output)
{
	struct config config;
	FILE *stream;
	struct LAR *lar;
	struct LARAttr attr;
	int i, j, ret = -1;
	struct lfile *lfiles;

	stream = fopen(input, "r");

	if (stream == NULL) {
		warn("E:  Couldn't open %s for reading\n", input);
		return -1;
	}

	memset(&config, 0, sizeof(config));

	parseconfig(stream, &config);
	fclose(stream);

	lar = LAR_Create(output);

	if (lar == NULL) {
		warn("E:  Couldn't create a new lar file\n");
		return -1;
	}

	LAR_SetCompressionFuncs(lar, ALGO_LZMA, do_lzma_compress, NULL);

	lfiles = calloc(sizeof(struct lfile), config.n_entries);

	if (lfiles == NULL) {
		warn("E: Couldn't allocate memory: %m\n");
		return -1;
	}

	for (i = 0; i < config.n_entries; i++) {
		/* Master chain entries don't have files associated with them. */
		if (config.entries[i]->type == BPT_TYPE_CHAIN)
			continue;

		if (access(config.entries[i]->file, R_OK)) {
			warn("E:  Could not find file %s\n",
			     config.entries[i]->file);

			goto err;
		}

		if (config.entries[i]->larname == NULL) {
			config.entries[i]->larname =
			    strdup(basename(config.entries[i]->file));

			if (config.entries[i]->larname == NULL) {
				warn("E: Could not allocate memory for the default name\n");
				goto err;
			}
		}

		/*
		 * Add the file to the list of files to add to the LAR - skip
		 * any duplicates, but be on the lookout for the same LAR name
		 * attached to a different file.
		 */
		for (j = 0; j < n_lfiles; j++) {
			if (!strcmp(lfiles[j].larname,
				    config.entries[i]->larname)) {
				if (strcmp(lfiles[j].file,
					   config.entries[i]->file)) {
					warn("E:  LAR name '%s' has already been used\n", config.entries[i]->larname);
					goto err;
				}
				break;
			}
		}

		if (j == n_lfiles) {
			lfiles[n_lfiles].file = config.entries[i]->file;
			lfiles[n_lfiles++].larname = config.entries[i]->larname;
		}
	}

	/* Add all the files to the LAR. */
	for (i = 0; i < n_lfiles; i++) {
		LAR_SetAttrs(&attr, lfiles[i].larname, ALGO_LZMA);

		if (LAR_AppendFile(lar, lfiles[i].file, &attr)) {
			warn("E: Could not add %s to the LAR\n",
			     lfiles[i].file);
			goto err;
		}
	}

	ret = add_bpt_to_lar(lar, &config);

err:
	LAR_Close(lar);
	return ret;
}
