/*
 * 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 "bayou.h"

struct bayoucfg bayoucfg;

static int add_payload(struct LAR *lar, struct larent *larent)
{
	struct payload *payload;
	int plen;
	u8 *params = NULL;
	u8 *fptr;

	if (bayoucfg.n_entries == BAYOU_MAX_ENTRIES)
		return -1;

	payload = &bayoucfg.entries[bayoucfg.n_entries];

	if (strncmp((char *)larent->name, "payload/", 8))
		return -1;

	if (larstat(lar, (const char *)larent->name, &payload->stat))
		return -1;

	/* Make sure the LAR entry is valid. */
	if (!lfverify(lar, (const char *)larent->name))
		return -1;

	/* Get a pointer to the start of the file. */
	fptr = larfptr(lar, (const char *)larent->name);

	if (fptr == NULL)
		return -1;

	if (!verify_self(fptr))
		return -1;

	payload->pentry.index = bayoucfg.n_entries;
	payload->pentry.parent = 0;
	payload->pentry.type = BPT_TYPE_CHOOSER;
	payload->pentry.flags = 0;

	plen = self_get_params(fptr, &params);
	payload_parse_params(payload, params, plen);

	payload->fptr = fptr;

	bayoucfg.n_entries++;

	return 0;
}

static int lar_walk_files(struct LAR *lar,
			  int (*cb) (struct LAR *, struct larent *))
{
	struct larent *larent;
	int ret = 0;

	rewindlar(lar);

	while ((larent = readlar(lar)) != NULL) {
		if ((ret = cb(lar, larent)))
			break;
	}

	return ret;
}

/**
 * If reading the bayou_payload_table fails for some reason, then construct
 * a dummy table. All valid payloads in the lar are added as chooser items.
 */
static void build_dummy_table(struct LAR *lar)
{
	bayoucfg.timeout = 0xFF;
	bayoucfg.n_entries = 0;

	lar_walk_files(lar, add_payload);
}

int get_configuration(struct LAR *lar)
{
	struct larstat stat;
	struct bpt_config *bptcfg;
	u8 *fptr, *ptr;
	int i;

	/*
	 * If bayou_payload_table doesn't exist, then dummy up
	 * a table from the LAR contents.
	 */
	if (larstat(lar, "bayou_payload_table", &stat) ||
	    !lfverify(lar, "bayou_payload_table"))
		build_dummy_table(lar);

	/* Open up the BPT and get the creamy goodness within. */

	fptr = larfptr(lar, "bayou_payload_table");

	if (fptr == NULL)
		build_dummy_table(lar);

	bptcfg = (struct bpt_config *)fptr;
	bayoucfg.timeout = bptcfg->timeout;

	bayoucfg.n_entries = bptcfg->entries;

	if (bayoucfg.n_entries > BAYOU_MAX_ENTRIES) {
		printf("W:  Limiting the number of entries to %d\n",
		       BAYOU_MAX_ENTRIES);
		bayoucfg.n_entries = BAYOU_MAX_ENTRIES;
	}

	ptr = fptr + sizeof(struct bpt_config);

	for (i = 0; i < bayoucfg.n_entries; i++) {
		struct bpt_pentry *entry = (struct bpt_pentry *)ptr;
		struct payload *p = &(bayoucfg.entries[i]);
		int plen;
		u8 *params = NULL;

		memcpy(&p->pentry, entry, sizeof(struct bpt_pentry));

		if (entry->type != BPT_TYPE_CHAIN) {
			char *lname = (char *)ptr + sizeof(struct bpt_pentry);

			if (larstat(lar, (const char *)lname, &p->stat))
				build_dummy_table(lar);

			if (!lfverify(lar, (const char *)lname))
				build_dummy_table(lar);

			fptr = larfptr(lar, (const char *)lname);

			if (verify_self(fptr))
				p->fptr = fptr;
			else
				build_dummy_table(lar);

			plen = self_get_params(fptr, &params);
			payload_parse_params(p, params, plen);
		}

		ptr += sizeof(struct bpt_pentry) + entry->nlen;
	}

	return 0;
}
