/* 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 struct username 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.name;
	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.
 *
 * Keep in mind that the expected behavior of gen functions that interoperate
 * with dev functions (e.g. devdirread()) is that files are directly genned, but
 * not directories.  Directories will fail to gen, and devstat() just makes
 * something up.  See also:
 * https://github.com/brho/plan9/blob/89d43d2262ad43eb4b26c2a8d6a27cfeddb33828/nix/sys/src/nix/port/dev.c#L74
 *
 * The comment about genning a file's siblings needs a grain of salt too.  Look
 * through ipgen().  I think it's what I call "direct genning." */
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.name, 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.name, 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
 * current->user.name
 */
void devpermcheck(char *fileuid, uint32_t perm, int omode)
{
	int rwx;

	/* select user, group, or other from the traditional rwxrwxrwx, shifting
	 * into the upper-most position */
	if (strcmp(current->user.name, fileuid) == 0)
		perm <<= 0;
	else if (iseve())
		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;
}
