/*
** ap.c -- parse addresses 822-style
**
** This code is Copyright (c) 2002, by the authors of nmh.  See the
** COPYRIGHT file in the root directory of the nmh distribution for
** complete copyright information.
*/

#include <h/mh.h>
#include <h/addrsbr.h>
#include <h/fmt_scan.h>
#include <h/utils.h>
#include <locale.h>
#include <sysexits.h>

#define NADDRS 100

#define FORMAT "=%<{error}%{error}: %{text}%|%(putstr(proper{text}))%>"

static struct swit switches[] = {
#define FORMSW 0
	{ "form formatfile", 0 },
#define NORMSW 1
	{ "normalize", 0 },
#define NNORMSW 2
	{ "nonormalize", 2 },
#define VERSIONSW 3
	{ "Version", 0 },
#define HELPSW 4
	{ "help", 0 },
	{ NULL, 0 }
};

char *version=VERSION;

static struct format *fmt;

static int dat[5];

/*
** static prototypes
*/
static int process(char *, int);


int
main(int argc, char **argv)
{
	int addrp = 0, normalize = AD_HOST;
	int status = 0;
	char *cp, *form = NULL, *fmtstr;
	char buf[BUFSIZ], **argp;
	char **arguments, *addrs[NADDRS];

	setlocale(LC_ALL, "");
	invo_name = mhbasename(argv[0]);

	/* read user profile/context */
	context_read();

	arguments = getarguments(invo_name, argc, argv, 1);
	argp = arguments;

	while ((cp = *argp++)) {
		if (*cp == '-') {
			switch (smatch(++cp, switches)) {
			case AMBIGSW:
				ambigsw(cp, switches);
				exit(EX_USAGE);

			case UNKWNSW:
				adios(EX_USAGE, NULL, "-%s unknown", cp);

			case HELPSW:
				snprintf(buf, sizeof(buf), "%s [switches] addrs ...", invo_name);
				print_help(buf, switches, 1);
				exit(argc == 2 ? EX_OK : EX_USAGE);
			case VERSIONSW:
				print_version(invo_name);
				exit(argc == 2 ? EX_OK : EX_USAGE);

			case FORMSW:
				if (!(form = *argp++) || *form == '-')
					adios(EX_USAGE, NULL, "missing argument to %s", argp[-2]);
				continue;

			case NORMSW:
				normalize = AD_HOST;
				continue;
			case NNORMSW:
				normalize = AD_NHST;
				continue;
			}
		}
		if (addrp > NADDRS)
			adios(EX_USAGE, NULL, "more than %d addresses", NADDRS);
		else
			addrs[addrp++] = cp;
	}
	addrs[addrp] = NULL;

	if (addrp == 0)
		adios(EX_USAGE, NULL, "usage: %s [switches] addrs ...", invo_name);

	/* get new format string */
	fmtstr = new_fs(form, FORMAT);

	fmt_norm = normalize;
	fmt_compile(fmtstr, &fmt);

	dat[0] = 0;
	dat[1] = 0;
	dat[2] = 0;
	dat[3] = BUFSIZ;
	dat[4] = 0;

	for (addrp = 0; addrs[addrp]; addrp++)
		status += process(addrs[addrp], normalize);

	return status;
}

struct pqpair {
	char *pq_text;
	char *pq_error;
	struct pqpair *pq_next;
};


static int
process(char *arg, int norm)
{
	int status = 0;
	char *cp;
	char buffer[BUFSIZ + 1], error[BUFSIZ];
	struct comp *cptr;
	struct pqpair *p, *q;
	struct pqpair pq;
	struct mailname *mp;

	(q = &pq)->pq_next = NULL;
	while ((cp = getname(arg))) {
		p = mh_xcalloc(1, sizeof(*p));
		if ((mp = getm(cp, NULL, 0, norm, error)) == NULL) {
			p->pq_text = mh_xstrdup(cp);
			p->pq_error = mh_xstrdup(error);
			status++;
		} else {
			p->pq_text = mh_xstrdup(mp->m_text);
			mnfree(mp);
		}
		q = (q->pq_next = p);
	}

	for (p = pq.pq_next; p; p = q) {
		FINDCOMP(cptr, "text");
		if (cptr)
			cptr->c_text = p->pq_text;
		FINDCOMP(cptr, "error");
		if (cptr)
			cptr->c_text = p->pq_error;

		fmt_scan(fmt, buffer, BUFSIZ, dat);
		fputs(buffer, stdout);

		mh_free0(&(p->pq_text));
		if (p->pq_error)
			mh_free0(&(p->pq_error));
		q = p->pq_next;
		mh_free0(&p);
	}

	return status;
}
