/* 
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */
#include <parlib/printf-ext.h>

#include <stdlib.h>
#include <stdio.h>
#include <parlib/parlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <error.h>
#include <iplib/iplib.h>
#include <fcall.h>
#include <ndblib/ndb.h>
#include <ndblib/fcallfmt.h>

static int dumpsome(FILE *, char *, long);
static int fdirconv(FILE *, struct dir *);
static char *qidtype(char *, uint8_t);

#define	QIDFMT	"(%.16llux %lud %s)"

int printf_fcall(FILE * stream, const struct printf_info *info,
				 const void *const *args)
{
	struct fcall *f = *(void **)args[0];
	int fid, type, tag, i, retval = 0;
	char buf[512], tmp[200];
	char *p, *e;
	struct dir *d;
	struct qid *q;

	e = buf + sizeof(buf);
	type = f->type;
	fid = f->fid;
	tag = f->tag;
	switch (type) {
		case Tversion:	/* 100 */
			retval +=
				fprintf(stream, "Tversion tag %u msize %u version '%s' ", tag,
						f->msize, f->version);
			break;
		case Rversion:
			retval +=
				fprintf(stream, "Rversion tag %u msize %u version '%s' ", tag,
						f->msize, f->version);
			break;
		case Tauth:	/* 102 */
			retval +=
				fprintf(stream, "Tauth tag %u afid %d uname %s aname %s ", tag,
						f->afid, f->uname, f->aname);
			break;
		case Rauth:
			retval += fprintf(stream, "Rauth tag %u qid " QIDFMT, tag,
							  f->aqid.path, f->aqid.vers, qidtype(tmp,
																  f->aqid.
																  type));
			break;
		case Tattach:	/* 104 */
			retval +=
				fprintf(stream,
						"Tattach tag %u fid %d afid %d uname %s aname %s ", tag,
						fid, f->afid, f->uname, f->aname);
			break;
		case Rattach:
			retval += fprintf(stream, "Rattach tag %u qid " QIDFMT, tag,
							  f->qid.path, f->qid.vers, qidtype(tmp,
																f->qid.type));
			break;
		case Rerror:	/* 107; 106 (Terror) illegal */
			retval += fprintf(stream, "Rerror tag %u ename %s ", tag, f->ename);
			break;
		case Tflush:	/* 108 */
			retval +=
				fprintf(stream, "Tflush tag %u oldtag %u ", tag, f->oldtag);
			break;
		case Rflush:
			retval += fprintf(stream, "Rflush tag %u ", tag);
			break;
		case Twalk:	/* 110 */
			retval +=
				fprintf(stream, "Twalk tag %u fid %d newfid %d nwname %d  ",
						tag, fid, f->newfid, f->nwname);
			if (f->nwname <= MAXWELEM)
				for (i = 0; i < f->nwname; i++)
					retval += fprintf(stream, "%d:%s  ", i, f->wname[i]);
			break;
		case Rwalk:
			retval +=
				fprintf(stream, "Rwalk tag %u nwqid %u  ", tag, f->nwqid);
			if (f->nwqid <= MAXWELEM)
				for (i = 0; i < f->nwqid; i++) {
					q = &f->wqid[i];
					retval += fprintf(stream, "%d:" QIDFMT "  ", i,
									  q->path, q->vers, qidtype(tmp, q->type));
				}
			break;
		case Topen:	/* 112 */
			retval +=
				fprintf(stream, "Topen tag %u fid %u mode %d ", tag, fid,
						f->mode);
			break;
		case Ropen:
			retval +=
				fprintf(stream, "Ropen tag %u qid " QIDFMT " iounit %u  ", tag,
						f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type),
						f->iounit);
			break;
		case Tcreate:	/* 114 */
			retval +=
				fprintf(stream,
						"Tcreate tag %u fid %u name %s perm %d mode %d ", tag,
						fid, f->name, (uint32_t) f->perm, f->mode);
			break;
		case Rcreate:
			retval +=
				fprintf(stream, "Rcreate tag %u qid " QIDFMT " iounit %u  ",
						tag, f->qid.path, f->qid.vers, qidtype(tmp,
															   f->qid.type),
						f->iounit);
			break;
		case Tread:	/* 116 */
			retval +=
				fprintf(stream, "Tread tag %u fid %d offset %lld count %u ",
						tag, fid, f->offset, f->count);
			break;
		case Rread:
			retval +=
				fprintf(stream, "Rread tag %u count %u  ", tag, f->count);
			retval += dumpsome(stream, f->data, f->count);
			break;
		case Twrite:	/* 118 */
			retval +=
				fprintf(stream, "Twrite tag %u fid %d offset %lld count %u  ",
						tag, fid, f->offset, f->count);
			retval += dumpsome(stream, f->data, f->count);
			break;
		case Rwrite:
			retval +=
				fprintf(stream, "Rwrite tag %u count %u ", tag, f->count);
			break;
		case Tclunk:	/* 120 */
			retval += fprintf(stream, "Tclunk tag %u fid %u ", tag, fid);
			break;
		case Rclunk:
			retval += fprintf(stream, "Rclunk tag %u ", tag);
			break;
		case Tremove:	/* 122 */
			retval += fprintf(stream, "Tremove tag %u fid %u ", tag, fid);
			break;
		case Rremove:
			retval += fprintf(stream, "Rremove tag %u ", tag);
			break;
		case Tstat:	/* 124 */
			retval += fprintf(stream, "Tstat tag %u fid %u ", tag, fid);
			break;
		case Rstat:
			retval += fprintf(stream, "Rstat tag %u  ", tag);
			if (f->nstat > sizeof tmp)
				retval += fprintf(stream, " stat(%d bytes) ", f->nstat);
			else {
				d = (struct dir *)tmp;
				convM2D(f->stat, f->nstat, d, (char *)(d + 1));
				retval += fprintf(stream, " stat ");
				retval += fdirconv(stream, d);
			}
			break;
		case Twstat:	/* 126 */
			retval += fprintf(stream, "Twstat tag %u fid %u ", tag, fid);
			if (f->nstat > sizeof tmp)
				retval += fprintf(stream, " stat(%d bytes) ", f->nstat);
			else {
				d = (struct dir *)tmp;
				convM2D(f->stat, f->nstat, d, (char *)(d + 1));
				retval += fprintf(stream, " stat ");
				retval += fdirconv(stream, d);
			}
			break;
		case Rwstat:
			retval += fprintf(stream, "Rwstat tag %u ", tag);
			break;
		default:
			retval += fprintf(stream, "unknown type %d ", type);
	}
	return retval;
}

static char *qidtype(char *s, uint8_t t)
{
	char *p;
#define QTDIR              0x80	/* type bit for directories */
	p = s;
	if (t & QTDIR)
		*p++ = 'd';
#if 0
	if (t & QTAPPEND)
		*p++ = 'a';
	if (t & QTEXCL)
		*p++ = 'l';
	if (t & QTAUTH)
		*p++ = 'A';
#endif
	*p = '\0';
	return s;
}

int printf_dir(FILE * stream, const struct printf_info *info,
			   const void *const *args)
{
	struct dir *d = *(void **)args[0];
	return fdirconv(stream, d);
}

static int fdirconv(FILE * stream, struct dir *d)
{
	char tmp[16];

	return fprintf(stream, "'%s' '%s' '%s' '%s' "
				   "q " QIDFMT " m %#luo "
				   "at %ld mt %ld l %lld "
				   "t %d d %d ",
				   d->name, d->uid, d->gid, d->muid,
				   d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
				   d->atime, d->mtime, d->length, d->type, d->dev);
}

/*
 * dump out count (or DUMPL, if count is bigger) bytes from
 * buf to stream, as a string if they are all printable,
 * else as a series of hex bytes
 */
#define DUMPL 64

static int dumpsome(FILE * stream, char *buf, long count)
{
	int i, printable, retval = 0;

	if (buf == NULL) {
		return fprintf(stream, "<no data>");
	}
	printable = 1;
	if (count > DUMPL)
		count = DUMPL;
	for (i = 0; i < count && printable; i++)
		if ((buf[i] < 32 && buf[i] != '\n' && buf[i] != '\t')
			|| (uint8_t) buf[i] > 127)
			printable = 0;
	retval += fprintf(stream, "'");
	if (printable) {
		retval += fprintf(stream, "%s ", buf);
	} else {
		for (i = 0; i < count; i++) {
			if (i > 0 && i % 4 == 0)
				retval += fprintf(stream, " ");
			retval += fprintf(stream, "%2.2ux ", buf[i]);
		}
	}
	retval += fprintf(stream, "'");
	return retval;
}

int printf_fcall_info(const struct printf_info *info, size_t n, int *argtypes,
					  int *size)
{
	if (n > 0) {
		argtypes[0] = PA_POINTER;
		size[0] = sizeof(uint8_t *);
	}
	return 1;
}

int printf_dir_info(const struct printf_info *info, size_t n, int *argtypes,
					int *size)
{
	if (n > 0) {
		argtypes[0] = PA_POINTER;
		size[0] = sizeof(uint8_t *);
	}
	return 1;
}
