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

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;
}
