/* Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 * Portions Copyright © 1997-1999 Vita Nuova Limited
 * Portions Copyright © 2000-2007 Vita Nuova Holdings Limited
 *                                (www.vitanuova.com)
 * Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 *
 * Modified for the Akaros operating system:
 * Copyright (c) 2013-2014 The Regents of the University of California
 * Copyright (c) 2013-2015 Google Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE. */

#include <vfs.h>
#include <kfs.h>
#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 <ip.h>

struct dev pipedevtab;

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

typedef struct Pipe Pipe;
struct Pipe {
	qlock_t qlock;
	Pipe *next;
	struct kref ref;
	uint32_t path;
	struct queue *q[2];
	int qref[2];
	struct dirtab *pipedir;
	char *user;
	struct fdtap_slist data_taps;
	spinlock_t tap_lock;
};

static struct {
	spinlock_t lock;
	uint32_t path;
	int pipeqsize;
} pipealloc;

enum {
	Qdir,
	Qctl,
	Qdata0,
	Qdata1,
};

static
struct dirtab pipedir[] = {
	{".", {Qdir, 0, QTDIR}, 0, DMDIR | 0500},
	{"ctl", {Qctl}, 0, 0660},
	{"data", {Qdata0}, 0, 0660},
	{"data1", {Qdata1}, 0, 0660},
};

static void freepipe(Pipe * p)
{
	if (p != NULL) {
		kfree(p->user);
		kfree(p->q[0]);
		kfree(p->q[1]);
		kfree(p->pipedir);
		kfree(p);
	}
}

static void pipe_release(struct kref *kref)
{
	Pipe *pipe = container_of(kref, Pipe, ref);
	freepipe(pipe);
}

static void pipeinit(void)
{
	pipealloc.pipeqsize = 32 * 1024;
}

/*
 *  create a pipe, no streams are created until an open
 */
static struct chan *pipeattach(char *spec)
{
	ERRSTACK(2);
	Pipe *p;
	struct chan *c;

	c = devattach(devname(), spec);
	p = kzmalloc(sizeof(Pipe), 0);
	if (p == 0)
		error(ENOMEM, ERROR_FIXME);
	if (waserror()) {
		freepipe(p);
		nexterror();
	}
	p->pipedir = kzmalloc(sizeof(pipedir), 0);
	if (p->pipedir == 0)
		error(ENOMEM, ERROR_FIXME);
	memmove(p->pipedir, pipedir, sizeof(pipedir));
	kstrdup(&p->user, current->user.name);
	kref_init(&p->ref, pipe_release, 1);
	qlock_init(&p->qlock);

	p->q[0] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
	if (p->q[0] == 0)
		error(ENOMEM, ERROR_FIXME);
	p->q[1] = qopen(pipealloc.pipeqsize, Qcoalesce, 0, 0);
	if (p->q[1] == 0)
		error(ENOMEM, ERROR_FIXME);
	poperror();

	spin_lock(&(&pipealloc)->lock);
	p->path = ++pipealloc.path;
	spin_unlock(&(&pipealloc)->lock);

	c->qid.path = NETQID(2 * p->path, Qdir);
	c->qid.vers = 0;
	c->qid.type = QTDIR;
	c->aux = p;
	c->dev = 0;

	/* taps. */
	SLIST_INIT(&p->data_taps);	/* already = 0; set to be futureproof */
	spinlock_init(&p->tap_lock);
	return c;
}

static int
pipegen(struct chan *c, char *unused,
		struct dirtab *tab, int ntab, int i, struct dir *dp)
{
	int id, len;
	struct qid qid;
	Pipe *p;

	if (i == DEVDOTDOT) {
		devdir(c, c->qid, devname(), 0, eve.name, 0555, dp);
		return 1;
	}
	i++;	/* skip . */
	if (tab == 0 || i >= ntab)
		return -1;
	tab += i;
	p = c->aux;
	switch (NETTYPE(tab->qid.path)) {
		case Qdata0:
			len = qlen(p->q[0]);
			break;
		case Qdata1:
			len = qlen(p->q[1]);
			break;
		default:
			len = tab->length;
			break;
	}
	id = NETID(c->qid.path);
	qid.path = NETQID(id, tab->qid.path);
	qid.vers = 0;
	qid.type = QTFILE;
	devdir(c, qid, tab->name, len, eve.name, tab->perm, dp);
	return 1;
}

static struct walkqid *pipewalk(struct chan *c, struct chan *nc, char **name,
								int nname)
{
	struct walkqid *wq;
	Pipe *p;

	p = c->aux;
	wq = devwalk(c, nc, name, nname, p->pipedir, ARRAY_SIZE(pipedir), pipegen);
	if (wq != NULL && wq->clone != NULL && wq->clone != c) {
		qlock(&p->qlock);
		kref_get(&p->ref, 1);
		if (c->flag & COPEN) {
			switch (NETTYPE(c->qid.path)) {
				case Qdata0:
					p->qref[0]++;
					break;
				case Qdata1:
					p->qref[1]++;
					break;
			}
		}
		qunlock(&p->qlock);
	}
	return wq;
}

static int pipestat(struct chan *c, uint8_t * db, int n)
{
	Pipe *p;
	struct dir dir;
	struct dirtab *tab;
	int perm;
	int type = NETTYPE(c->qid.path);

	p = c->aux;
	tab = p->pipedir;

	switch (type) {
		case Qdir:
		case Qctl:
			devdir(c, c->qid, tab[type].name, tab[type].length, eve.name,
			       tab[type].perm, &dir);
			break;
		case Qdata0:
			perm = tab[1].perm;
			perm |= qreadable(p->q[0]) ? DMREADABLE : 0;
			perm |= qwritable(p->q[1]) ? DMWRITABLE : 0;
			devdir(c, c->qid, tab[1].name, qlen(p->q[0]), eve.name, perm, &dir);
			break;
		case Qdata1:
			perm = tab[2].perm;
			perm |= qreadable(p->q[1]) ? DMREADABLE : 0;
			perm |= qwritable(p->q[0]) ? DMWRITABLE : 0;
			devdir(c, c->qid, tab[2].name, qlen(p->q[1]), eve.name, perm, &dir);
			break;
		default:
			panic("pipestat");
	}
	n = convD2M(&dir, db, n);
	if (n < BIT16SZ)
		error(ENODATA, ERROR_FIXME);
	return n;
}

/*
 *  if the stream doesn't exist, create it
 */
static struct chan *pipeopen(struct chan *c, int omode)
{
	ERRSTACK(2);
	Pipe *p;

	if (c->qid.type & QTDIR) {
		if (omode & O_WRITE)
			error(EINVAL, "Can only open directories O_READ, mode is %o oct",
				  omode);
		c->mode = openmode(omode);
		c->flag |= COPEN;
		c->offset = 0;
		return c;
	}

	openmode(omode);	/* check it */

	p = c->aux;
	qlock(&p->qlock);
	if (waserror()) {
		qunlock(&p->qlock);
		nexterror();
	}
	switch (NETTYPE(c->qid.path)) {
		case Qdata0:
			devpermcheck(p->user, p->pipedir[1].perm, omode);
			p->qref[0]++;
			break;
		case Qdata1:
			devpermcheck(p->user, p->pipedir[2].perm, omode);
			p->qref[1]++;
			break;
	}
	poperror();
	qunlock(&p->qlock);

	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}

static void pipeclose(struct chan *c)
{
	Pipe *p;

	p = c->aux;
	qlock(&p->qlock);

	if (c->flag & COPEN) {
		/*
		 *  closing either side hangs up the stream
		 */
		switch (NETTYPE(c->qid.path)) {
			case Qdata0:
				p->qref[0]--;
				if (p->qref[0] == 0) {
					qhangup(p->q[1], 0);
					qclose(p->q[0]);
				}
				break;
			case Qdata1:
				p->qref[1]--;
				if (p->qref[1] == 0) {
					qhangup(p->q[0], 0);
					qclose(p->q[1]);
				}
				break;
		}
	}

	/*
	 *  if both sides are closed, they are reusable
	 */
	if (p->qref[0] == 0 && p->qref[1] == 0) {
		qreopen(p->q[0]);
		qreopen(p->q[1]);
	}

	qunlock(&p->qlock);
	/*
	 *  free the structure on last close
	 */
	kref_put(&p->ref);
}

static long piperead(struct chan *c, void *va, long n, int64_t offset)
{
	Pipe *p;

	p = c->aux;

	switch (NETTYPE(c->qid.path)) {
		case Qdir:
			return devdirread(c, va, n, p->pipedir, ARRAY_SIZE(pipedir),
							  pipegen);
		case Qctl:
			return readnum(offset, va, n, p->path, NUMSIZE32);
		case Qdata0:
			if (c->flag & O_NONBLOCK)
				return qread_nonblock(p->q[0], va, n);
			else
				return qread(p->q[0], va, n);
		case Qdata1:
			if (c->flag & O_NONBLOCK)
				return qread_nonblock(p->q[1], va, n);
			else
				return qread(p->q[1], va, n);
		default:
			panic("piperead");
	}
	return -1;	/* not reached */
}

static struct block *pipebread(struct chan *c, long n, uint32_t offset)
{
	Pipe *p;

	p = c->aux;

	switch (NETTYPE(c->qid.path)) {
		case Qdata0:
			if (c->flag & O_NONBLOCK)
				return qbread_nonblock(p->q[0], n);
			else
				return qbread(p->q[0], n);
		case Qdata1:
			if (c->flag & O_NONBLOCK)
				return qbread_nonblock(p->q[1], n);
			else
				return qbread(p->q[1], n);
	}

	return devbread(c, n, offset);
}

/*
 *  A write to a closed pipe causes an EPIPE error to be thrown.
 */
static long pipewrite(struct chan *c, void *va, long n, int64_t ignored)
{
	ERRSTACK(1);
	Pipe *p;
	struct cmdbuf *cb;

	p = c->aux;

	switch (NETTYPE(c->qid.path)) {
		case Qctl:
			cb = parsecmd(va, n);
			if (waserror()) {
				kfree(cb);
				nexterror();
			}
			if (cb->nf < 1)
				error(EFAIL, "short control request");
			if (strcmp(cb->f[0], "oneblock") == 0) {
				q_toggle_qmsg(p->q[0], TRUE);
				q_toggle_qcoalesce(p->q[0], TRUE);
				q_toggle_qmsg(p->q[1], TRUE);
				q_toggle_qcoalesce(p->q[1], TRUE);
			} else {
				error(EFAIL, "unknown control request");
			}
			kfree(cb);
			poperror();
			break;

		case Qdata0:
			if (c->flag & O_NONBLOCK)
				n = qwrite_nonblock(p->q[1], va, n);
			else
				n = qwrite(p->q[1], va, n);
			break;

		case Qdata1:
			if (c->flag & O_NONBLOCK)
				n = qwrite_nonblock(p->q[0], va, n);
			else
				n = qwrite(p->q[0], va, n);
			break;

		default:
			panic("pipewrite");
	}

	return n;
}

static long pipebwrite(struct chan *c, struct block *bp, uint32_t offset)
{
	long n;
	Pipe *p;
	//Prog *r;

	p = c->aux;
	switch (NETTYPE(c->qid.path)) {
		case Qctl:
			return devbwrite(c, bp, offset);
		case Qdata0:
			if (c->flag & O_NONBLOCK)
				n = qbwrite_nonblock(p->q[1], bp);
			else
				n = qbwrite(p->q[1], bp);
			break;

		case Qdata1:
			if (c->flag & O_NONBLOCK)
				n = qbwrite_nonblock(p->q[0], bp);
			else
				n = qbwrite(p->q[0], bp);
			break;

		default:
			n = 0;
			panic("pipebwrite");
	}

	return n;
}

static int pipewstat(struct chan *c, uint8_t *dp, int n)
{
	ERRSTACK(2);
	struct dir *d;
	Pipe *p;
	int d1;

	if (c->qid.type & QTDIR)
		error(EPERM, ERROR_FIXME);
	p = c->aux;
	if (strcmp(current->user.name, p->user) != 0)
		error(EPERM, ERROR_FIXME);
	d = kzmalloc(sizeof(*d) + n, 0);
	if (waserror()) {
		kfree(d);
		nexterror();
	}
	n = convM2D(dp, n, d, (char *)&d[1]);
	if (n == 0)
		error(ENODATA, ERROR_FIXME);
	d1 = NETTYPE(c->qid.path) == Qdata1;
	if (!emptystr(d->name)) {
		validwstatname(d->name);
		if (strlen(d->name) >= KNAMELEN)
			error(ENAMETOOLONG, ERROR_FIXME);
		if (strncmp(p->pipedir[1 + !d1].name, d->name, KNAMELEN) == 0)
			error(EEXIST, ERROR_FIXME);
		strncpy(p->pipedir[1 + d1].name, d->name, KNAMELEN);
	}
	if (d->mode != -1)
		p->pipedir[d1 + 1].perm = d->mode & 0777;
	poperror();
	kfree(d);
	return n;
}

static char *pipechaninfo(struct chan *chan, char *ret, size_t ret_l)
{
	Pipe *p = chan->aux;

	switch (NETTYPE(chan->qid.path)) {
	case Qdir:
		snprintf(ret, ret_l, "Qdir, ID %d", p->path);
		break;
	case Qctl:
		snprintf(ret, ret_l, "Qctl, ID %d", p->path);
		break;
	case Qdata0:
		snprintf(ret, ret_l, "Qdata%d, ID %d, %s, rq len %d, wq len %d",
		         0, p->path,
		         SLIST_EMPTY(&p->data_taps) ? "untapped" : "tapped",
		         qlen(p->q[0]),
		         qlen(p->q[1]));
		break;
	case Qdata1:
		snprintf(ret, ret_l, "Qdata%d, ID %d, %s, rq len %d, wq len %d",
		         1, p->path,
		         SLIST_EMPTY(&p->data_taps) ? "untapped" : "tapped",
		         qlen(p->q[1]),
		         qlen(p->q[0]));
		break;
	default:
		ret = "Unknown type";
		break;
	}
	return ret;
}

/* We pass the pipe as data.  The pipe will outlive any potential qio callbacks.
 * Meaning, we don't need to worry about the pipe disappearing if we're in here.
 * If we're in here, then the q exists, which means the pipe exists.
 *
 * However, the chans do not necessarily exist.  The taps keep the chans around.
 * So we only know which chan we're firing when we look at an individual tap. */
static void pipe_wake_cb(struct queue *q, void *data, int filter)
{
	Pipe *p = (Pipe*)data;
	struct fd_tap *tap_i;
	struct chan *chan;

	spin_lock(&p->tap_lock);
	SLIST_FOREACH(tap_i, &p->data_taps, link) {
		chan = tap_i->chan;
		/* Depending which chan did the tapping, we'll care about different
		 * filters on different qs.  For instance, if we tapped Qdata0, then we
		 * only care about readables on q[0], writables on q[1], and hangups on
		 * either.  More precisely, we don't care about writables on q[0] or
		 * readables on q[1].
		 *
		 * Note the *tap's* filter might differ from the CB's filter.  The CB
		 * could be for read|write|hangup on q[1], with a Qdata0 tap for just
		 * read.  We don't want to just pass the CB filt directly to fire_tap,
		 * since that would pass the CB's read on q[1] to the tap and fire.  The
		 * user would think q[0] was readable.  This is why I mask out the CB
		 * filter events that we know they don't want. */
		switch (NETTYPE(chan->qid.path)) {
		case Qdata0:
			if (q == p->q[0])
				filter &= ~FDTAP_FILT_WRITABLE;
			else
				filter &= ~FDTAP_FILT_READABLE;
			break;
		case Qdata1:
			if (q == p->q[1])
				filter &= ~FDTAP_FILT_WRITABLE;
			else
				filter &= ~FDTAP_FILT_READABLE;
			break;
		default:
			panic("Shouldn't be able to tap pipe qid %p", chan->qid.path);
		}
		fire_tap(tap_i, filter);
	}
	spin_unlock(&p->tap_lock);
}

static int pipetapfd(struct chan *chan, struct fd_tap *tap, int cmd)
{
	int ret;
	Pipe *p;

	p = chan->aux;
#define DEVPIPE_LEGAL_DATA_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE | \
                                 FDTAP_FILT_HANGUP | FDTAP_FILT_ERROR)

	switch (NETTYPE(chan->qid.path)) {
	case Qdata0:
	case Qdata1:
		if (tap->filter & ~DEVPIPE_LEGAL_DATA_TAPS) {
			set_errno(ENOSYS);
			set_errstr("Unsupported #%s data tap %p, must be %p", devname(),
			           tap->filter, DEVPIPE_LEGAL_DATA_TAPS);
			return -1;
		}
		spin_lock(&p->tap_lock);
		switch (cmd) {
		case (FDTAP_CMD_ADD):
			if (SLIST_EMPTY(&p->data_taps)) {
				qio_set_wake_cb(p->q[0], pipe_wake_cb, p);
				qio_set_wake_cb(p->q[1], pipe_wake_cb, p);
			}
			SLIST_INSERT_HEAD(&p->data_taps, tap, link);
			ret = 0;
			break;
		case (FDTAP_CMD_REM):
			SLIST_REMOVE(&p->data_taps, tap, fd_tap, link);
			if (SLIST_EMPTY(&p->data_taps)) {
				qio_set_wake_cb(p->q[0], 0, p);
				qio_set_wake_cb(p->q[1], 0, p);
			}
			ret = 0;
			break;
		default:
			set_errno(ENOSYS);
			set_errstr("Unsupported #%s data tap command %p", devname(), cmd);
			ret = -1;
		}
		spin_unlock(&p->tap_lock);
		return ret;
	default:
		set_errno(ENOSYS);
		set_errstr("Can't tap #%s file type %d", devname(),
		           NETTYPE(chan->qid.path));
		return -1;
	}
}

struct dev pipedevtab __devtab = {
	.name = "pipe",

	.reset = devreset,
	.init = pipeinit,
	.shutdown = devshutdown,
	.attach = pipeattach,
	.walk = pipewalk,
	.stat = pipestat,
	.open = pipeopen,
	.create = devcreate,
	.close = pipeclose,
	.read = piperead,
	.bread = pipebread,
	.write = pipewrite,
	.bwrite = pipebwrite,
	.remove = devremove,
	.wstat = pipewstat,
	.power = devpower,
	.chaninfo = pipechaninfo,
	.tapfd = pipetapfd,
};
