/* Copyright (c) 2015 Google Inc
 * Davide Libenzi <dlibenzi@google.com>
 * See LICENSE for details.
 */

#include <ros/common.h>
#include <ros/errno.h>
#include <smp.h>
#include <ns.h>
#include <kmalloc.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <err.h>
#include <build_info.h>

enum {
	Kverdirqid = 0,
	Kverbuildid,
	Kverdate,
	Kvercommitid,
	Kverversion,
	Kverversionname,
	BUILD_ID_SZ = 20,
	BUILD_ID_OFFSET = 16,
};

struct dev verdevtab;
static struct dirtab vertab[] = {
	{".",				{Kverdirqid,		0, QTDIR}, 0,	DMDIR|0550},
	{"build_id",		{Kverbuildid},		0,	0444},
	{"date",			{Kverdate},			0,	0444},
	{"commitid",		{Kvercommitid},		0,	0444},
	{"version",			{Kverversion},		0,	0444},
	{"version_name",	{Kverversionname},	0,	0444},
};

extern char __note_build_id_start[];
extern char __note_build_id_end[];

static char *get_build_id_start(void)
{
	return __note_build_id_start + BUILD_ID_OFFSET;
}

static size_t build_id_sz(void)
{
	return __note_build_id_end - get_build_id_start();
}

static long ver_emit_nlstr(char *dest, const char *src, long size,
						   long offset)
{
	long n, slen = strlen(src);
	char *buf = kmalloc(slen + 1, MEM_WAIT);

	snprintf(buf, slen + 1, "%s", src);
	n = readmem(offset, dest, size, buf, slen + 1);
	kfree(buf);

	return n;
}

static size_t ver_get_file_size(const char *src)
{
	if (!src)
		return 0;
	return strlen(src) + 1;
}

static struct chan *ver_attach(char *spec)
{
	return devattach(verdevtab.name, spec);
}

static void ver_init(void)
{
	/* Our devtab's length params are wrong - need to stitch them up. */
	vertab[Kverbuildid].length = build_id_sz();
	vertab[Kverdate].length = ver_get_file_size(build_info_date);
	vertab[Kvercommitid].length = ver_get_file_size(build_info_commitid);
	vertab[Kverversion].length = ver_get_file_size(build_info_version);
	vertab[Kverversionname].length = ver_get_file_size(build_info_version_name);
}

static void ver_shutdown(void)
{

}

static struct walkqid *ver_walk(struct chan *c, struct chan *nc, char **name,
								 int nname)
{
	return devwalk(c, nc, name, nname, vertab, ARRAY_SIZE(vertab), devgen);
}

static int ver_stat(struct chan *c, uint8_t *db, int n)
{
	return devstat(c, db, n, vertab, ARRAY_SIZE(vertab), devgen);
}

static struct chan *ver_open(struct chan *c, int omode)
{
	if (c->qid.type & QTDIR) {
		if (openmode(omode) != O_READ)
			error(EPERM, ERROR_FIXME);
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	return c;
}

static void ver_close(struct chan *c)
{

}

/* Returns a char representing the lowest 4 bits of x */
static char num_to_nibble(int x)
{
	return "0123456789abcdef"[x % 16];
}

static ssize_t read_buildid(void *va, long n, off64_t off)
{
	/* Each build_id byte needs 2 chars, and 1 for the \0 */
	char build_id[BUILD_ID_SZ * 2 + 1] = {0};
	uint8_t hi, lo;
	uint8_t *b = (uint8_t*)get_build_id_start();

	for (int i = 0; i < BUILD_ID_SZ; i++) {
		hi = *b >> 4;
		lo = *b & 0xf;
		build_id[i * 2 + 0] = num_to_nibble(hi);
		build_id[i * 2 + 1] = num_to_nibble(lo);
		b++;
	}
	return readmem(off, va, n, build_id, sizeof(build_id));
}

static long ver_read(struct chan *c, void *va, long n, int64_t off)
{
	switch ((int) c->qid.path) {
	case Kverdirqid:
		return devdirread(c, va, n, vertab, ARRAY_SIZE(vertab), devgen);
	case Kverbuildid:
		return read_buildid(va, n, off);
	case Kverdate:
		if (build_info_date)
			return ver_emit_nlstr(va, build_info_date, n, (long) off);
		break;
	case Kvercommitid:
		if (build_info_commitid)
			return ver_emit_nlstr(va, build_info_commitid, n, (long) off);
		break;
	case Kverversion:
		if (build_info_version)
			return ver_emit_nlstr(va, build_info_version, n, (long) off);
		break;
	case Kverversionname:
		if (build_info_version_name)
			return ver_emit_nlstr(va, build_info_version_name, n, (long) off);
		break;
	default:
		error(EINVAL, ERROR_FIXME);
	}

	return 0;
}

static long ver_write(struct chan *c, void *a, long n, int64_t unused)
{
	error(ENOTSUP, ERROR_FIXME);
	return -1;
}

struct dev verdevtab __devtab = {
	.name = "version",

	.reset = devreset,
	.init = ver_init,
	.shutdown = ver_shutdown,
	.attach = ver_attach,
	.walk = ver_walk,
	.stat = ver_stat,
	.open = ver_open,
	.create = devcreate,
	.close = ver_close,
	.read = ver_read,
	.bread = devbread,
	.write = ver_write,
	.bwrite = devbwrite,
	.remove = devremove,
	.wstat = devwstat,
};
