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

extern uint32_t kerndate;
extern char *eve;

void mkqid(struct qid *q, int64_t path, uint32_t vers, int type)
{
	q->type = type;
	q->vers = vers;
	q->path = path;
}

int devno(const char *name, int user)
{
	int i;

	for (i = 0; &devtab[i] < __devtabend; i++) {
		if (!strcmp(devtab[i].name, name))
			return i;
	}
	if (user == 0)
		panic("Lookup of dev :%s: failed", name);

	return -1;
}

void
devdir(struct chan *c, struct qid qid, char *n,
	   int64_t length, char *user, long perm, struct dir *db)
{
	db->name = n;
	if (c->flag & CMSG)
		qid.type |= QTMOUNT;
	db->qid = qid;
	db->type = c->type;	/* used to use the dev's dc here */
	db->dev = c->dev;
	db->mode = perm;
	db->mode |= qid.type << 24;
	db->atime = seconds();
	db->mtime = kerndate;
	db->length = length;
	db->uid = user;
	db->gid = eve;
	db->muid = user;
}

/*
 * The zeroth element of the table MUST be the directory itself, or '.' (dot),
 * for processing '..' (dot-dot). Specifically, if i==DEVDOTDOT, we call devdir
 * on the *directory* (that is, dot), as opposed to children of the directory.
 * The rest of the system assumes that the first entry in the table refers to
 * the directory, and by convention this is named '.' (dot). This is confusing.
 *
 * Any entry with qid verion of -1 will return 0, indicating that the value is
 * valid but there is nothing there, so continue walking.
 *
 * TODO(cross): Document devgen and clean this mess up. Devgen should probably
 * be removed and replaced with a smarter data structure.
 */
int
devgen(struct chan *c, char *unused_name, struct dirtab *tab, int ntab,
       int i, struct dir *dp)
{
	if (tab == NULL)
		return -1;
	if (i != DEVDOTDOT) {
		/* Skip over the first element, that for the directory itself. */
		i++;
		if (i < 0 || ntab <= i)
			return -1;
		tab += i;
	}
	if (tab->qid.vers == -1)
		return 0;
	devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp);
	return 1;
}

void devreset(void)
{
}

void devinit(void)
{
}

void devshutdown(void)
{
}

struct chan *devattach(const char *name, char *spec)
{
	struct chan *c;
	char *buf;
	size_t buflen;

	c = newchan();
	mkqid(&c->qid, 0, 0, QTDIR);
	c->type = devno(name, 0);
	if (spec == NULL)
		spec = "";
	/* 1 for #, 1 for ., 1 for \0 */
	buflen = strlen(name) + strlen(spec) + 3;
	buf = kzmalloc(buflen, MEM_WAIT);
	snprintf(buf, sizeof(buf), "#%s.%s", name, spec);
	c->name = newcname(buf);
	kfree(buf);
	return c;
}

struct chan *devclone(struct chan *c)
{
	struct chan *nc;

	/* In plan 9, you couldn't clone an open chan.  We're allowing it, possibly
	 * foolishly.  The new chan is a non-open, "kernel internal" chan.  Note
	 * that c->flag isn't set, for instance.  c->mode is, which might be a
	 * problem.  The newchan should eventually have a device's open called on
	 * it, at which point it upgrades from a kernel internal chan to one that
	 * can refer to an object in the device (e.g. grab a refcnt on a
	 * conversation in #ip).
	 *
	 * Either we allow devclones of open chans, or O_PATH walks do not open a
	 * file.  It's nice to allow the device to do something for O_PATH, but
	 * perhaps that is not critical.  However, if we can't clone an opened chan,
	 * then we can *only* openat from an FD that is O_PATH, which is not the
	 * spec (and not as useful). */
	if ((c->flag & COPEN) && !(c->flag & O_PATH))
		panic("clone of non-O_PATH open file type %s\n", devtab[c->type].name);

	nc = newchan();
	nc->type = c->type;
	nc->dev = c->dev;
	nc->mode = c->mode;
	nc->qid = c->qid;
	nc->offset = c->offset;
	nc->umh = NULL;
	nc->mountid = c->mountid;
	nc->aux = c->aux;
	nc->mqid = c->mqid;
	nc->mcp = c->mcp;
	return nc;
}

struct walkqid *devwalk(struct chan *c,
						struct chan *nc, char **name, int nname,
						struct dirtab *tab, int ntab, Devgen * gen)
{
	ERRSTACK(1);
	int i, j;
	volatile int alloc;			/* to keep waserror from optimizing this out */
	struct walkqid *wq;
	char *n;
	struct dir dir;

	if (nname > 0)
		isdir(c);

	alloc = 0;
	wq = kzmalloc(sizeof(struct walkqid) + nname * sizeof(struct qid),
				  MEM_WAIT);
	if (waserror()) {
		if (alloc && wq->clone != NULL)
			cclose(wq->clone);
		kfree(wq);
		poperror();
		return NULL;
	}
	if (nc == NULL) {
		nc = devclone(c);
		/* inferno was setting this to 0, assuming it was devroot.  lining up
		 * with chanrelease and newchan */
		nc->type = -1;	/* device doesn't know about this channel yet */
		alloc = 1;
	}
	wq->clone = nc;

	dir.qid.path = 0;
	for (j = 0; j < nname; j++) {
		if (!(nc->qid.type & QTDIR)) {
			if (j == 0)
				error(ENOTDIR, ERROR_FIXME);
			goto Done;
		}
		n = name[j];
		if (strcmp(n, ".") == 0) {
Accept:
			wq->qid[wq->nqid++] = nc->qid;
			continue;
		}
		if (strcmp(n, "..") == 0) {
			(*gen) (nc, NULL, tab, ntab, DEVDOTDOT, &dir);
			nc->qid = dir.qid;
			goto Accept;
		}
		/*
		 * Ugly problem: If we're using devgen, make sure we're
		 * walking the directory itself, represented by the first
		 * entry in the table, and not trying to step into a sub-
		 * directory of the table, e.g. /net/net. Devgen itself
		 * should take care of the problem, but it doesn't have
		 * the necessary information (that we're doing a walk).
		 */
		if (gen == devgen && nc->qid.path != tab[0].qid.path)
			goto Notfound;
		dir.qid.path = 0;
		for (i = 0;; i++) {
			switch ((*gen) (nc, n, tab, ntab, i, &dir)) {
				case -1:
					printd("DEVWALK -1, i was %d, want path %p\n", i,
						   c->qid.path);
Notfound:
					if (j == 0)
						error(ENOENT, "could not find name %s, dev %s", n,
						      c->type == -1 ? "no dev" : devtab[c->type].name);
					/* TODO: I think we don't need to just set_error here */
					set_error(ENOENT, "tell brho you saw this in an error");
					goto Done;
				case 0:
					printd("DEVWALK continue, i was %d\n", i);
					continue;
				case 1:
					printd
						("DEVWALK gen returns path %p name %s, want path %p\n",
						 dir.qid.path, dir.name, c->qid.path);
					if (strcmp(n, dir.name) == 0) {
						nc->qid = dir.qid;
						goto Accept;
					}
					continue;
			}
		}
	}
	/*
	 * We processed at least one name, so will return some data.
	 * If we didn't process all nname entries succesfully, we drop
	 * the cloned channel and return just the Qids of the walks.
	 */
Done:
	poperror();
	if (wq->nqid < nname) {
		if (alloc)
			cclose(wq->clone);
		wq->clone = NULL;
	} else if (wq->clone) {
		/* attach cloned channel to same device */
		wq->clone->type = c->type;
	}
	return wq;
}

/* Helper, makes a stat in @dp, given @n bytes, from chan @c's contents in @dir.
 * Throws on error, returns the size used on success. */
size_t dev_make_stat(struct chan *c, struct dir *dir, uint8_t *dp, size_t n)
{
	if (c->flag & CMSG)
		dir->mode |= DMMOUNT;
	n = convD2M(dir, dp, n);
	if (n == 0)
		error(EINVAL, ERROR_FIXME);
	return n;
}

int
devstat(struct chan *c, uint8_t * db, int n,
		struct dirtab *tab, int ntab, Devgen * gen)
{
	int i;
	struct dir dir;
	char *p, *elem;

	dir.qid.path = 0;
	for (i = 0;; i++)
		switch ((*gen) (c, NULL, tab, ntab, i, &dir)) {
			case -1:
				if (c->qid.type & QTDIR) {
					printd("DEVSTAT got a dir: %llu\n", c->qid.path);
					if (c->name == NULL)
						elem = "???";
					else if (strcmp(c->name->s, "/") == 0)
						elem = "/";
					else
						for (elem = p = c->name->s; *p; p++)
							if (*p == '/')
								elem = p + 1;
					devdir(c, c->qid, elem, 0, eve, DMDIR | 0555, &dir);
					n = convD2M(&dir, db, n);
					if (n == 0)
						error(EINVAL, ERROR_FIXME);
					return n;
				}
				printd("DEVSTAT fails:%s %llu\n", devtab[c->type].name,
					   c->qid.path);
				error(ENOENT, ERROR_FIXME);
			case 0:
				printd("DEVSTAT got 0\n");
				break;
			case 1:
				printd("DEVSTAT gen returns path %p name %s, want path %p\n",
					   dir.qid.path, dir.name, c->qid.path);
				if (c->qid.path == dir.qid.path)
					return dev_make_stat(c, &dir, db, n);
				break;
		}
}

long
devdirread(struct chan *c, char *d, long n,
		   struct dirtab *tab, int ntab, Devgen * gen)
{
	long m, dsz;
	/* this is gross. Make it 2 so we have room at the end for
	 * bad things.
	 */
	struct dir dir[4];

	dir[0].qid.path = 0;
	for (m = 0; m < n; c->dri++) {
		switch ((*gen) (c, NULL, tab, ntab, c->dri, &dir[0])) {
			case -1:
				printd("DEVDIRREAD got -1, asked for s = %d\n", c->dri);
				return m;

			case 0:
				printd("DEVDIRREAD got 0, asked for s = %d\n", c->dri);
				break;

			case 1:
				printd("DEVDIRREAD got 1, asked for s = %d\n", c->dri);
				dsz = convD2M(&dir[0], (uint8_t *) d, n - m);
				if (dsz <= BIT16SZ) {	/* <= not < because this isn't stat; read is stuck */
					if (m == 0)
						error(ENODATA, ERROR_FIXME);
					return m;
				}
				m += dsz;
				d += dsz;
				break;
		}
	}

	return m;
}

/*
 * error(EPERM, ERROR_FIXME) if open permission not granted for up->env->user.
 */
void devpermcheck(char *fileuid, uint32_t perm, int omode)
{
	int rwx;

	/* TODO: Implement permission checking, for now permission is always
	 * granted. */
	return;
	/* select user, group, or other from the traditional rwxrwxrwx, shifting
	 * into the upper-most position */
	if (strcmp(current->user, fileuid) == 0)
		perm <<= 0;
	else if (strcmp(current->user, eve) == 0)
		perm <<= 3;
	else
		perm <<= 6;
	/* translate omode into things like S_IRUSR (just one set of rwx------).
	 * Plan 9 originally only returned 0400 0200 0600 and 0100 here; it didn't
	 * seem to handle O_EXEC being mixed readable or writable. */
	rwx = omode_to_rwx(omode);
	if ((rwx & perm) != rwx)
		error(EPERM, "devpermcheck(%s, 0%o, 0%o) failed", fileuid, perm, omode);
}

struct chan *devopen(struct chan *c, int omode, struct dirtab *tab, int ntab,
					 Devgen * gen)
{
	int i;
	struct dir dir;

	dir.qid.path = 0;
	for (i = 0;; i++) {
		switch ((*gen) (c, NULL, tab, ntab, i, &dir)) {
			case -1:
				goto Return;
			case 0:
				break;
			case 1:
				if (c->qid.path == dir.qid.path) {
					devpermcheck(dir.uid, dir.mode, omode);
					goto Return;
				}
				break;
		}
	}
Return:
	c->offset = 0;
	if ((c->qid.type & QTDIR) && (omode & O_WRITE))
		error(EACCES, "Tried opening dir with non-read-only mode %o", omode);
	c->mode = openmode(omode);
	c->flag |= COPEN;
	return c;
}

void
devcreate(struct chan *c, char *unused_char_p_t, int unused_int, uint32_t u)
{
	error(EPERM, ERROR_FIXME);
}

struct block *devbread(struct chan *c, long n, uint32_t offset)
{
	ERRSTACK(1);
	struct block *bp;

	bp = block_alloc(n, MEM_WAIT);
	if (bp == 0)
		error(ENOMEM, ERROR_FIXME);
	if (waserror()) {
		freeb(bp);
		nexterror();
	}
	bp->wp += devtab[c->type].read(c, bp->wp, n, offset);
	poperror();
	return bp;
}

long devbwrite(struct chan *c, struct block *bp, uint32_t offset)
{
	ERRSTACK(1);
	long n;

	if (waserror()) {
		freeb(bp);
		nexterror();
	}
	n = devtab[c->type].write(c, bp->rp, BLEN(bp), offset);
	poperror();
	freeb(bp);

	return n;
}

void devremove(struct chan *c)
{
	error(EPERM, ERROR_FIXME);
}

int devwstat(struct chan *c, uint8_t * unused_uint8_p_t, int i)
{
	error(EPERM, ERROR_FIXME);
	return 0;
}

void devpower(int i)
{
	error(EPERM, ERROR_FIXME);
}

#if 0
int devconfig(int unused_int, char *c, DevConf *)
{
	error(EPERM, ERROR_FIXME);
	return 0;
}
#endif

char *devchaninfo(struct chan *chan, char *ret, size_t ret_l)
{
	snprintf(ret, ret_l, "qid.path: %p, qid.type: %02x", chan->qid.path,
			 chan->qid.type);
	return ret;
}

/*
 * check that the name in a wstat is plausible
 */
void validwstatname(char *name)
{
	validname(name, 0);
	if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
		error(EINVAL, ERROR_FIXME);
}

struct dev *devbyname(char *name)
{
	int i;

	for (i = 0; &devtab[i] < __devtabend; i++)
		if (strcmp(devtab[i].name, name) == 0)
			return &devtab[i];
	return NULL;
}
