/*
 * Copyright (C) 2018 Synaptics Incorporated. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND
 * SYNAPTICS EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE, AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY
 * INTELLECTUAL PROPERTY RIGHTS. IN NO EVENT SHALL SYNAPTICS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, OR
 * CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION WITH THE USE
 * OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED AND
 * BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF
 * COMPETENT JURISDICTION DOES NOT PERMIT THE DISCLAIMER OF DIRECT
 * DAMAGES OR ANY OTHER DAMAGES, SYNAPTICS' TOTAL CUMULATIVE LIABILITY
 * TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. DOLLARS.
 */

#include <stdint.h>
#include <stdarg.h>

#include "util.h"
#include "apb_uart_drv.h"

#if 0
#include "usb_common.h"

static uint32_t output_string_buf_head;
void reset_usb_console(void)
{
	output_string_buf_head = *(uint32_t*)USB_SOC_OUTPUT_WRITE_PTR;
	if (output_string_buf_head == 0){
		output_string_buf_head = USB_SOC_OUTPUT_STRING_BUF;
	}
}

void usb_putc(int ch)
{
	*(char *)((uintmax_t)output_string_buf_head) = (char) ch;
	output_string_buf_head ++;
	if (output_string_buf_head >= USB_SOC_OUTPUT_STRING_BUF_ROLL_POINT){
		//roll back to start of the buffer, for next entire string.
		*(uint32_t *)USB_SOC_OUTPUT_EOS_PTR = output_string_buf_head;
		output_string_buf_head = USB_SOC_OUTPUT_STRING_BUF;
	}
	*(uint32_t *)USB_SOC_OUTPUT_WRITE_PTR = output_string_buf_head;
}
#endif

int putchar(int c){
	APB_UART_putc(0, c) ; 
#if 0
	usb_putc(c);
#endif
	if (c == '\n'){
		APB_UART_putc(0, '\r');
#if 0
		usb_putc('\r');
		flush_dcache_range((void *)USB_SOC_OUTPUT_WRITE_PTR,
				   (void *)ALIGNED(USB_SOC_OUTPUT_STRING_BUF + USB_SOC_STRING_BUF_SIZE));
#endif
	}
	//Both usb_putc and UART_putc return void hence return 0
	return 0;
}

void printchar(char **str, unsigned long *remain, int c)
{

	if (str) {
		if (remain) {
			if (*remain == 0)
				return;

			// Only one spot left, nul terminate.
			if (*remain == 1)
				c = '\0';
			--(*remain);
		}

		**str = c;
		++(*str);
	}
	else (void)putchar(c);
}

#define PAD_RIGHT 1
#define PAD_ZERO 2

int prints(char **out, unsigned long *remain, const char *string, int width, int pad)
{
	register int pc = 0, padchar = ' ';

	if (width > 0) {
		register int len = 0;
		register const char *ptr;
		for (ptr = string; *ptr; ++ptr) ++len;
		if (len >= width) width = 0;
		else width -= len;
		if (pad & PAD_ZERO) padchar = '0';
	}
	if (!(pad & PAD_RIGHT)) {
		for ( ; width > 0; --width) {
			printchar (out, remain, padchar);
			++pc;
		}
	}
	for ( ; *string ; ++string) {
		printchar (out, remain, *string);
		++pc;
	}
	for ( ; width > 0; --width) {
		printchar (out, remain, padchar);
		++pc;
	}

	return pc;
}

/* the following should be enough for 32 bit int */
#define PRINT_BUF_LEN 12

int printi(char **out, unsigned long* remain, int i, int b, int sg, int width, int pad, int letbase)
{
	char print_buf[PRINT_BUF_LEN];
	register char *s;
	register int t, neg = 0, pc = 0;
	register unsigned int u = i;

	if (i == 0) {
		print_buf[0] = '0';
		print_buf[1] = '\0';
		return prints (out, remain, print_buf, width, pad);
	}

	if (sg && b == 10 && i < 0) {
		neg = 1;
		u = -i;
	}

	s = print_buf + PRINT_BUF_LEN-1;
	*s = '\0';

	while (u) {
		t = u % b;
		if( t >= 10 )
			t += letbase - '0' - 10;
		*--s = t + '0';
		u /= b;
	}

	if (neg) {
		if( width && (pad & PAD_ZERO) ) {
			printchar (out, remain, '-');
			++pc;
			--width;
		}
		else {
			*--s = '-';
		}
	}

	return pc + prints (out, remain, s, width, pad);
}

static int print(char **out, unsigned long *remain, const char *format, va_list ap)
{
	register int width, pad;
	register int pc = 0;
	char scr[2];

	for (; *format != 0; ++format) {
		if (*format == '%') {
			++format;
			width = pad = 0;
			if (*format == '\0') break;
			if (*format == '%') goto out;
			if (*format == '-') {
				++format;
				pad = PAD_RIGHT;
			}
			while (*format == '0') {
				++format;
				pad |= PAD_ZERO;
			}
			for ( ; *format >= '0' && *format <= '9'; ++format) {
				width *= 10;
				width += *format - '0';
			}
			if( *format == 's' ) {
				register char *s = va_arg(ap, char *);
				pc += prints (out, remain, s?s:"(null)", width, pad);
				continue;
			}
			if( *format == 'd' ) {
				pc += printi (out, remain, va_arg(ap, int), 10, 1, width, pad, 'a');
				continue;
			}
			if( *format == 'x' ) {
				pc += printi (out, remain, va_arg(ap, int), 16, 0, width, pad, 'a');
				continue;
			}
			if( *format == 'X' ) {
				pc += printi (out, remain, va_arg(ap, int), 16, 0, width, pad, 'A');
				continue;
			}
			if( *format == 'u' ) {
				pc += printi (out, remain, va_arg(ap, int), 10, 0, width, pad, 'a');
				continue;
			}
			if( *format == 'c' ) {
				/* char are converted to int then pushed on the stack */
				scr[0] = va_arg(ap, int);
				scr[1] = '\0';
				pc += prints (out, remain, scr, width, pad);
				continue;
			}
		}
		else {
		out:
			printchar (out, remain, *format);
			++pc;
		}
	}
	if (out) **out = '\0';
	return pc;
}

#if 1
int lgpl_printf(const char *format, ...)
{
	int rv;
	va_list ap;

	va_start(ap, format);
	rv = print(0, NULL, format, ap);
	va_end(ap);

	return rv;
}
#endif

int printf(const char *format, ...)
{
	int rv;
	va_list ap;

	va_start(ap, format);
	rv = print(0, NULL, format, ap);
	va_end(ap);

	return rv;
}

#if 1
int lgpl_sprintf(char *out, const char *format, ...)
{
	int rv;
	va_list ap;

	va_start(ap, format);
	rv = print(&out, NULL, format, ap);
	va_end(ap);

	return rv;
}
#endif

int sprintf(char *out, const char *format, ...)
{
	int rv;
	va_list ap;

	va_start(ap, format);
	rv = print(&out, NULL, format, ap);
	va_end(ap);

	return rv;
}

int snprintf(char *out, unsigned long size, const char *format, ...)
{
	int rv;
	va_list ap;

	va_start(ap, format);
	rv = print(&out, &size, format, ap);
	va_end(ap);

	return rv;
}

/*
 * if you compile this file with
 *   gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
 * you will get a normal warning:
 *   printf.c:214: warning: spurious trailing `%' in format
 * this line is testing an invalid % at the end of the format string.
 *
 * this should display (on 32bit int machine) :
 *
 * Hello world!
 * printf test
 * (null) is null pointer
 * 5 = 5
 * -2147483647 = - max int
 * char a = 'a'
 * hex ff = ff
 * hex 00 = 00
 * signed -3 = unsigned 4294967293 = hex fffffffd
 * 0 message(s)
 * 0 message(s) with %
 * justif: "left      "
 * justif: "     right"
 *  3: 0003 zero padded
 *  3: 3    left justif.
 *  3:    3 right justif.
 * -3: -003 zero padded
 * -3: -3   left justif.
 * -3:   -3 right justif.
 */

