/*
 * Parse a simple file with messages, e.g used for USSD messages
 *
 * (C) 2010 by Holger Hans Peter Freyther
 * (C) 2010 by On-Waves
 * All Rights Reserved
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include <osmocom/core/msgfile.h>
#include <osmocom/core/talloc.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

static struct msg_entry *alloc_entry(struct msg_entries *entries,
				     const char *mcc, const char *mnc,
				     const char *option, const char *text)
{
	struct msg_entry *entry = talloc_zero(entries, struct msg_entry);
	if (!entry)
		return NULL;

	entry->mcc = talloc_strdup(entry, mcc);
	entry->mnc = talloc_strdup(entry, mnc);
	entry->option = talloc_strdup(entry, option);
	entry->text = talloc_strdup(entry, text);

	llist_add_tail(&entry->list, &entries->entry);
	return entry;
}

static struct msg_entries *alloc_entries(void *ctx)
{
	struct msg_entries *entries;

	entries = talloc_zero(ctx, struct msg_entries);
	if (!entries)
		return NULL;

	INIT_LLIST_HEAD(&entries->entry);
	return entries;
}

/*
 * split a line like 'foo:Text'.
 */
static void handle_line(struct msg_entries *entries, char *line)
{
	int i;
	const int len = strlen(line);

	char *items[3];
	int last_item = 0;

	/* Skip comments from the file */
	if (line[0] == '#')
		return;

	for (i = 0; i < len; ++i) {
		if (line[i] == '\n' || line[i] == '\r')
			line[i] = '\0';
		else if (line[i] == ':' && last_item < 3) {
			line[i] = '\0';

			items[last_item++] = &line[i + 1];
		}
	}

	if (last_item == 3) {
		alloc_entry(entries, &line[0] , items[0], items[1], items[2]);
		return;
	}

	/* nothing found */
}

struct msg_entries *msg_entry_parse(void *ctx, const char *filename)
{
	struct msg_entries *entries;
	size_t n;
	char *line;
	FILE *file;

	file = fopen(filename, "r");
	if (!file)
		return NULL;

	entries = alloc_entries(ctx);
	if (!entries) {
		fclose(file);
		return NULL;
	}

	n = 2342;
	line = NULL;
        while (getline(&line, &n, file) != -1) {
		handle_line(entries, line);
		free(line);
		line = NULL;
	}

	fclose(file);
	return entries;
}
