/* 
 * 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 <printf-ext.h>

#include <stdlib.h>
#include <stdio.h>
#include <parlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <pthread.h>
#include <fcntl.h>
#include <ctype.h>
#include <error.h>
#include <iplib.h>
#include <fcall.h>
#include <ndb.h>
#include <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;
}
