/* 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 <net/ip.h>

enum {
	Nlog = 4 * 1024,
};

/*
 *  action log
 */
struct Netlog {
	spinlock_t lock;
	int opens;
	char *buf;
	char *end;
	char *rptr;
	int len;

	int logmask;				/* mask of things to debug */
	uint8_t iponly[IPaddrlen];	/* ip address to print debugging for */
	int iponlyset;

	qlock_t qlock;
	struct rendez r;
};

typedef struct Netlogflag {
	char *name;
	int mask;
} Netlogflag;

static Netlogflag flags[] = {
	{"ppp", Logppp,},
	{"ip", Logip,},
	{"fs", Logfs,},
	{"tcp", Logtcp,},
	{"il", Logil,},
	{"icmp", Logicmp,},
	{"udp", Logudp,},
	{"compress", Logcompress,},
	{"ilmsg", Logil | Logilmsg,},
	{"gre", Loggre,},
	{"tcpreset", Logtcp | Logtcpreset,},
	{"tcprxmt", Logtcp | Logtcprxmt,},
	{"tcpall", Logtcp | Logtcpreset | Logtcprxmt | Logtcpverbose,},
	{"udpmsg", Logudp | Logudpmsg,},
	{"ipmsg", Logip | Logipmsg,},
	{"esp", Logesp,},
	{NULL, 0,},
};

enum {
	CMset,
	CMclear,
	CMonly,
};

static
struct cmdtab routecmd[] = {
	{CMset, "set", 0},
	{CMclear, "clear", 0},
	{CMonly, "only", 0},
};

void netloginit(struct Fs *f)
{
	f->alog = kzmalloc(sizeof(struct Netlog), 0);
	spinlock_init(&f->alog->lock);
	qlock_init(&f->alog->qlock);
	rendez_init(&f->alog->r);
}

void netlogopen(struct Fs *f)
{
	ERRSTACK(1);
	spin_lock(&f->alog->lock);
	if (waserror()) {
		spin_unlock(&f->alog->lock);
		nexterror();
	}
	if (f->alog->opens == 0) {
		if (f->alog->buf == NULL)
			f->alog->buf = kzmalloc(Nlog, 0);
		f->alog->rptr = f->alog->buf;
		f->alog->end = f->alog->buf + Nlog;
	}
	f->alog->opens++;
	spin_unlock(&f->alog->lock);
	poperror();
}

void netlogclose(struct Fs *f)
{
	ERRSTACK(1);
	spin_lock(&f->alog->lock);
	if (waserror()) {
		spin_unlock(&f->alog->lock);
		nexterror();
	}
	f->alog->opens--;
	if (f->alog->opens == 0) {
		kfree(f->alog->buf);
		f->alog->buf = NULL;
	}
	spin_unlock(&f->alog->lock);
	poperror();
}

static int netlogready(void *a)
{
	struct Fs *f = a;

	return f->alog->len;
}

long netlogread(struct Fs *f, void *a, uint32_t unused, long n)
{
	ERRSTACK(1);
	int i, d;
	char *p, *rptr;

	qlock(&f->alog->qlock);
	if (waserror()) {
		qunlock(&f->alog->qlock);
		nexterror();
	}

	for (;;) {
		spin_lock(&f->alog->lock);
		if (f->alog->len) {
			if (n > f->alog->len)
				n = f->alog->len;
			d = 0;
			rptr = f->alog->rptr;
			f->alog->rptr += n;
			if (f->alog->rptr >= f->alog->end) {
				d = f->alog->rptr - f->alog->end;
				f->alog->rptr = f->alog->buf + d;
			}
			f->alog->len -= n;
			spin_unlock(&f->alog->lock);

			i = n - d;
			p = a;
			memmove(p, rptr, i);
			memmove(p + i, f->alog->buf, d);
			break;
		} else
			spin_unlock(&f->alog->lock);

		rendez_sleep(&f->alog->r, netlogready, f);
	}

	qunlock(&f->alog->qlock);
	poperror();

	return n;
}

void netlogctl(struct Fs *f, char *s, int n)
{
	ERRSTACK(1);
	int i, set = 0;
	Netlogflag *fp;
	struct cmdbuf *cb;
	struct cmdtab *ct;

	cb = parsecmd(s, n);
	if (waserror()) {
		kfree(cb);
		nexterror();
	}

	if (cb->nf < 2)
		error(EINVAL, ERROR_FIXME);

	ct = lookupcmd(cb, routecmd, ARRAY_SIZE(routecmd));

	switch (ct->index) {
		case CMset:
			set = 1;
			break;

		case CMclear:
			set = 0;
			break;

		case CMonly:
			parseip(f->alog->iponly, cb->f[1]);
			if (ipcmp(f->alog->iponly, IPnoaddr) == 0)
				f->alog->iponlyset = 0;
			else
				f->alog->iponlyset = 1;
			kfree(cb);
			poperror();
			return;

		default:
			cmderror(cb, "unknown ip control message");
	}

	for (i = 1; i < cb->nf; i++) {
		for (fp = flags; fp->name; fp++)
			if (strcmp(fp->name, cb->f[i]) == 0)
				break;
		if (fp->name == NULL)
			continue;
		if (set)
			f->alog->logmask |= fp->mask;
		else
			f->alog->logmask &= ~fp->mask;
	}

	kfree(cb);
	poperror();
}

void netlog(struct Fs *f, int mask, char *fmt, ...)
{
	char buf[256], *t, *fp;
	int i, n;
	va_list arg;
	struct timespec ts_now;

	if (!(f->alog->logmask & mask))
		return;

	if (f->alog->opens == 0)
		return;

	/* Same style as trace_printk */
	if (likely(__proc_global_info.tsc_freq))
		ts_now = tsc2timespec(read_tsc());
	n = snprintf(buf, sizeof(buf), "[%lu.%09lu]: ",
	             ts_now.tv_sec, ts_now.tv_nsec);

	va_start(arg, fmt);
	n += vsnprintf(buf + n, sizeof(buf) - n, fmt, arg);
	va_end(arg);

	spin_lock(&f->alog->lock);
	i = f->alog->len + n - Nlog;
	if (i > 0) {
		f->alog->len -= i;
		f->alog->rptr += i;
		if (f->alog->rptr >= f->alog->end)
			f->alog->rptr = f->alog->buf + (f->alog->rptr - f->alog->end);
	}
	t = f->alog->rptr + f->alog->len;
	fp = buf;
	f->alog->len += n;
	while (n-- > 0) {
		if (t >= f->alog->end)
			t = f->alog->buf + (t - f->alog->end);
		*t++ = *fp++;
	}
	spin_unlock(&f->alog->lock);

	rendez_wakeup(&f->alog->r);
}
