/*
 * 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.
 */

// regression device.
// Currently, has only one file, monitor, which is used to send
// commands to the monitor.
// TODO: read them back :-)

#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <net/ip.h>
#include <monitor.h>
#include <ktest.h>

struct dev regressdevtab;

static char *devname(void)
{
	return regressdevtab.name;
}

struct regress
{
	spinlock_t lock;
	struct queue *monitor;
};
struct regress regress;

enum{
	Monitordirqid = 0,
	Monitordataqid,
	Monitorctlqid,
};

struct dirtab regresstab[]={
	{".",		{Monitordirqid, 0, QTDIR},	0,	DMDIR|0550},
	{"mondata",	{Monitordataqid},		0,	0600},
	{"monctl",	{Monitorctlqid},		0,	0600},
};

static char *ctlcommands = "ktest";

static struct chan *regressattach(char *spec)
{
	uint32_t n;

	regress.monitor = qopen(2 << 20, 0, 0, 0);
	if (! regress.monitor) {
		printk("monitor allocate failed. No monitor output\n");
	}
	return devattach(devname(), spec);
}

static void regressinit(void)
{
}

static struct walkqid *regresswalk(struct chan *c, struct chan *nc, char **name,
                                   unsigned int nname)
{
	return devwalk(c, nc, name, nname, regresstab, ARRAY_SIZE(regresstab),
	               devgen);
}

static size_t regressstat(struct chan *c, uint8_t *db, size_t n)
{
	if (regress.monitor)
		regresstab[Monitordataqid].length = qlen(regress.monitor);
	else
		regresstab[Monitordataqid].length = 0;

	return devstat(c, db, n, regresstab, ARRAY_SIZE(regresstab), devgen);
}

static struct chan *regressopen(struct chan *c, int omode)
{
	if (c->qid.type & QTDIR) {
		if (openmode(omode) != O_READ)
			error(EPERM, ERROR_FIXME);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

static void regressclose(struct chan *unused)
{
}

static size_t regressread(struct chan *c, void *va, size_t n, off64_t off)
{
	uint64_t w, *bp;
	char *a, *ea;
	uintptr_t offset = off;
	uint64_t pc;
	int snp_ret, ret = 0;

	switch((int)c->qid.path){
	case Monitordirqid:
		n = devdirread(c, va, n, regresstab, ARRAY_SIZE(regresstab),
			       devgen);
		break;

	case Monitorctlqid:
		n = readstr(off, va, n, ctlcommands);
		break;

	case Monitordataqid:
		if (regress.monitor) {
			printd("monitordataqid: regress.monitor %p len %p\n",
			       regress.monitor, qlen(kprof.monitor));
			if (qlen(regress.monitor) > 0)
				n = qread(regress.monitor, va, n);
			else
				n = 0;
		} else
			error(EFAIL, "no monitor queue");
		break;
	default:
		n = 0;
		break;
	}
	return n;
}

static size_t regresswrite(struct chan *c, void *a, size_t n, off64_t unused)
{
	ERRSTACK(1);
	uintptr_t pc;
	struct cmdbuf *cb;
	cb = parsecmd(a, n);

	if (waserror()) {
		kfree(cb);
		nexterror();
	}

	switch((int)(c->qid.path)){
	case Monitorctlqid:
		if(strncmp(a, "ktest", 5) == 0){
			run_registered_ktest_suites();
		} else {
			error(EFAIL, "regresswrite: only commands are %s",
			      ctlcommands);
		}
		break;

	case Monitordataqid:
		if (onecmd(cb->nf, cb->f, NULL) < 0)
			n = -1;
		break;
	default:
		error(EBADFD, ERROR_FIXME);
	}
	kfree(cb);
	poperror();
	return n;
}

struct dev regressdevtab __devtab = {
	.name = "regress",

	.reset = devreset,
	.init = regressinit,
	.shutdown = devshutdown,
	.attach = regressattach,
	.walk = regresswalk,
	.stat = regressstat,
	.open = regressopen,
	.create = devcreate,
	.close = regressclose,
	.read = regressread,
	.bread = devbread,
	.write = regresswrite,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
};
