/* Copyright (c) 2013-14 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Common printf format extensions.  For now, %r is installed by default
 * (in early init code), and the others need to be requested.
 *
 * To register, for example %i for ipaddr, call:
 * 	register_printf_specifier('i', printf_ipaddr, printf_ipaddr_info);
 *
 * __printf_ipaddr, printf_ipmask, and printf_ethaddr adapted from Inferno's
 * eipconvtest.c.  Their copyright:
 *
 * 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
 *
 * 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 <parlib/printf-ext.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

static bool is_ipv4(uint8_t *ipaddr)
{
	uint8_t v4prefix[] = {
		0, 0, 0, 0,
		0, 0, 0, 0,
		0, 0, 0xff, 0xff
	};
	return memcmp(ipaddr, v4prefix, sizeof(v4prefix)) == 0;
}

/* Helper, prints a formatted ipaddr to stream. */
static int __printf_ipaddr(FILE *stream, uint8_t *ipaddr)
{
	int i, j, eln, eli;
	int ret = 0;
	uint16_t s;

	if (is_ipv4(ipaddr))
		return fprintf(stream, "%d.%d.%d.%d", ipaddr[12], ipaddr[13],
		               ipaddr[14], ipaddr[15]);
	/* find longest elision */
	eln = eli = -1;
	for (i = 0; i < 16; i += 2) {
		for (j = i; j < 16; j += 2)
			if (ipaddr[j] != 0 || ipaddr[j + 1] != 0)
				break;
		if (j > i && j - i > eln) {
			eli = i;
			eln = j - i;
		}
	}
	/* print with possible elision */
	for (i = 0; i < 16; i += 2) {
		if (i == eli) {
			ret += fprintf(stream, "::");
			i += eln;
			if (i >= 16)
				break;
		} else if (i != 0)
			ret += fprintf(stream, ":");
		s = (ipaddr[i] << 8) + ipaddr[i + 1];
		ret += fprintf(stream, "%x", s);
	}
	return ret;
}

int printf_ipaddr(FILE *stream, const struct printf_info *info,
                  const void *const *args)
{
	/* args is an array of pointers, each of which points to an arg.
	 * to extract: TYPE x = *(TYPE*)args[n]. */
	uint8_t *ipaddr = *(uint8_t**)args[0];
	return __printf_ipaddr(stream, ipaddr);
}

int printf_ipaddr_info(const struct printf_info* info, size_t n, int *argtypes,
                       int *size)
{
	/* seems like this is how many va_args we will use, and how big each was
	 * we're supposed to fill up to n, i think.  we're only doing one */
	if (n > 0) {
		argtypes[0] = PA_POINTER;
		size[0] = sizeof(uint8_t*);
	}
	/* returns the nr of args required by the format string, no matter what
	 */
	return 1;
}

int printf_ipmask(FILE *stream, const struct printf_info *info,
                  const void *const *args)
{
	enum {
		Isprefix = 16,
	};
	static uint8_t prefixvals[256] = {
		[0x00] 0 | Isprefix,
		[0x80] 1 | Isprefix,
		[0xC0] 2 | Isprefix,
		[0xE0] 3 | Isprefix,
		[0xF0] 4 | Isprefix,
		[0xF8] 5 | Isprefix,
		[0xFC] 6 | Isprefix,
		[0xFE] 7 | Isprefix,
		[0xFF] 8 | Isprefix,
	};

	uint8_t *ipmask = *(uint8_t**)args[0];
	int i, j, n;
	/* look for a prefix mask */
	for (i = 0; i < 16; i++)
		if (ipmask[i] != 0xff)
			break;
	if (i < 16) {
		if ((prefixvals[ipmask[i]] & Isprefix) == 0)
			return __printf_ipaddr(stream, ipmask);
		for (j = i + 1; j < 16; j++)
			if (ipmask[j] != 0)
				return __printf_ipaddr(stream, ipmask);
		n = 8 * i + (prefixvals[ipmask[i]] & ~Isprefix);
	} else
		n = 8 * 16;
	/* got one, use /xx format */
	return fprintf(stream, "/%d", n);
}

int printf_ipmask_info(const struct printf_info* info, size_t n, int *argtypes,
                       int *size)
{
	if (n > 0) {
		argtypes[0] = PA_POINTER;
		size[0] = sizeof(uint8_t*);
	}
	return 1;
}

int printf_ethaddr(FILE *stream, const struct printf_info *info,
                   const void *const *args)
{
	uint8_t *e = *(uint8_t**)args[0];

	if (!e)
		e = "\0\0\0\0\0\0";
	return fprintf(stream, "%02x:%02x:%02x:%02x:%02x:%02x",
		       e[0], e[1], e[2], e[3], e[4], e[5]);
}

int printf_ethaddr_info(const struct printf_info* info, size_t n, int *argtypes,
                        int *size)
{
	if (n > 0) {
		argtypes[0] = PA_POINTER;
		size[0] = sizeof(uint8_t*);
	}
	return 1;
}

int printf_errstr(FILE *stream, const struct printf_info *info,
                  const void *const *args)
{
	return fprintf(stream, "%s", errstr());
}

int printf_errstr_info(const struct printf_info* info, size_t n, int *argtypes,
                       int *size)
{
	/* errstr consumes no arguments */
	return 0;
}

static char num_to_nibble(unsigned int x)
{
	return "0123456789abcdef"[x & 0xf];
}

int printf_hexdump(FILE *stream, const struct printf_info *info,
                   const void *const *args)
{
	uint8_t *arg = *(uint8_t**)args[0];
	char *buf, *p;
	int ret;

	/* 3 chars per byte, one for the space */
	buf = malloc(3 * info->prec);
	p = buf;
	for (int i = 0; i < info->prec; i++) {
		if (i)
			*p++ = ' ';
		*p++ = num_to_nibble(*arg >> 4);
		*p++ = num_to_nibble(*arg);
		arg++;
	}
	ret =  fwrite(buf, 1, p - buf, stream);
	free(buf);
	return ret;
}

int printf_hexdump_info(const struct printf_info *info, size_t n, int *argtypes,
                        int *size)
{
	if (n > 0) {
		argtypes[0] = PA_POINTER;
		size[0] = sizeof(uint8_t*);
	}
	return 1;
}
