/*
 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005
 *
 * Released under the terms of the GNU GPL v2.0
 */

#include <stdlib.h>
#include <string.h>

#include "lkc.h"

static char *escape(const char* text, char *bf, int len)
{
	char *bfp = bf;
	int multiline = strchr(text, '\n') != NULL;
	int eol = 0;
	int textlen = strlen(text);

	if ((textlen > 0) && (text[textlen-1] == '\n'))
		eol = 1;

	*bfp++ = '"';
	--len;

	if (multiline) {
		*bfp++ = '"';
		*bfp++ = '\n';
		*bfp++ = '"';
		len -= 3;
	}

	while (*text != '\0' && len > 1) {
		if (*text == '"')
			*bfp++ = '\\';
		else if (*text == '\n') {
			*bfp++ = '\\';
			*bfp++ = 'n';
			*bfp++ = '"';
			*bfp++ = '\n';
			*bfp++ = '"';
			len -= 5;
			++text;
			goto next;
		}
		else if (*text == '\\') {
			*bfp++ = '\\';
			len--;
		}
		*bfp++ = *text++;
next:
		--len;
	}

	if (multiline && eol)
		bfp -= 3;

	*bfp++ = '"';
	*bfp = '\0';

	return bf;
}

struct file_line {
	struct file_line *next;
	const char *file;
	int lineno;
};

static struct file_line *file_line__new(const char *file, int lineno)
{
	struct file_line *self = malloc(sizeof(*self));

	if (self == NULL)
		goto out;

	self->file   = file;
	self->lineno = lineno;
	self->next   = NULL;
out:
	return self;
}

struct message {
	const char	 *msg;
	const char	 *option;
	struct message	 *next;
	struct file_line *files;
};

static struct message *message__list;

static struct message *message__new(const char *msg, char *option,
				    const char *file, int lineno)
{
	struct message *self = malloc(sizeof(*self));

	if (self == NULL)
		goto out;

	self->files = file_line__new(file, lineno);
	if (self->files == NULL)
		goto out_fail;

	self->msg = xstrdup(msg);
	if (self->msg == NULL)
		goto out_fail_msg;

	self->option = option;
	self->next = NULL;
out:
	return self;
out_fail_msg:
	free(self->files);
out_fail:
	free(self);
	self = NULL;
	goto out;
}

static struct message *mesage__find(const char *msg)
{
	struct message *m = message__list;

	while (m != NULL) {
		if (strcmp(m->msg, msg) == 0)
			break;
		m = m->next;
	}

	return m;
}

static int message__add_file_line(struct message *self, const char *file,
				  int lineno)
{
	int rc = -1;
	struct file_line *fl = file_line__new(file, lineno);

	if (fl == NULL)
		goto out;

	fl->next    = self->files;
	self->files = fl;
	rc = 0;
out:
	return rc;
}

static int message__add(const char *msg, char *option, const char *file,
			int lineno)
{
	int rc = 0;
	char bf[16384];
	char *escaped = escape(msg, bf, sizeof(bf));
	struct message *m = mesage__find(escaped);

	if (m != NULL)
		rc = message__add_file_line(m, file, lineno);
	else {
		m = message__new(escaped, option, file, lineno);

		if (m != NULL) {
			m->next	      = message__list;
			message__list = m;
		} else
			rc = -1;
	}
	return rc;
}

static void menu_build_message_list(struct menu *menu)
{
	struct menu *child;

	message__add(menu_get_prompt(menu), NULL,
		     menu->file == NULL ? "Root Menu" : menu->file->name,
		     menu->lineno);

	if (menu->sym != NULL && menu_has_help(menu))
		message__add(menu_get_help(menu), menu->sym->name,
			     menu->file == NULL ? "Root Menu" : menu->file->name,
			     menu->lineno);

	for (child = menu->list; child != NULL; child = child->next)
		if (child->prompt != NULL)
			menu_build_message_list(child);
}

static void message__print_file_lineno(struct message *self)
{
	struct file_line *fl = self->files;

	putchar('\n');
	if (self->option != NULL)
		printf("# %s:00000\n", self->option);

	printf("#: %s:%d", fl->file, fl->lineno);
	fl = fl->next;

	while (fl != NULL) {
		printf(", %s:%d", fl->file, fl->lineno);
		fl = fl->next;
	}

	putchar('\n');
}

static void message__print_gettext_msgid_msgstr(struct message *self)
{
	message__print_file_lineno(self);

	printf("msgid %s\n"
	       "msgstr \"\"\n", self->msg);
}

static void menu__xgettext(void)
{
	struct message *m = message__list;

	while (m != NULL) {
		/* skip empty lines ("") */
		if (strlen(m->msg) > sizeof("\"\""))
			message__print_gettext_msgid_msgstr(m);
		m = m->next;
	}
}

int main(int ac, char **av)
{
	conf_parse(av[1]);

	menu_build_message_list(menu_get_root_menu(NULL));
	menu__xgettext();
	return 0;
}
