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

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,
				unsigned 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 size_t pipestat(struct chan *c, uint8_t *db, size_t 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 size_t piperead(struct chan *c, void *va, size_t n, off64_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, size_t n, off64_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 size_t pipewrite(struct chan *c, void *va, size_t n, off64_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 size_t pipebwrite(struct chan *c, struct block *bp, off64_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 size_t pipewstat(struct chan *c, uint8_t *dp, size_t 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);
		strlcpy(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, total read %llu",
		         0, p->path,
		         SLIST_EMPTY(&p->data_taps) ? "untapped" : "tapped",
		         qlen(p->q[0]),
		         qlen(p->q[1]), q_bytes_read(p->q[0]));
		break;
	case Qdata1:
		snprintf(ret, ret_l,
		         "Qdata%d, ID %d, %s, rq len %d, wq len %d, total read %llu",
		         1, p->path,
		         SLIST_EMPTY(&p->data_taps) ? "untapped" : "tapped",
		         qlen(p->q[1]),
		         qlen(p->q[0]), q_bytes_read(p->q[1]));
		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;
	}
}

static unsigned long pipe_chan_ctl(struct chan *c, int op, unsigned long a1,
                                   unsigned long a2, unsigned long a3,
                                   unsigned long a4)
{
	switch (op) {
	case CCTL_SET_FL:
		return 0;
	default:
		error(EINVAL, "%s does not support %d", __func__, op);
	}
}

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,
	.chan_ctl = pipe_chan_ctl,
};
