// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include "cache.h"
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include "color.h"
#include <math.h>
#include <unistd.h>

int perf_use_color_default = -1;

int perf_config_colorbool(const char *var, const char *value, int stdout_is_tty)
{
	if (value) {
		if (!strcasecmp(value, "never"))
			return 0;
		if (!strcasecmp(value, "always"))
			return 1;
		if (!strcasecmp(value, "auto"))
			goto auto_color;
	}

	/* Missing or explicit false to turn off colorization */
	if (!perf_config_bool(var, value))
		return 0;

	/* any normal truth value defaults to 'auto' */
 auto_color:
	if (stdout_is_tty < 0)
		stdout_is_tty = isatty(1);
	if (stdout_is_tty || pager_in_use()) {
		char *term = getenv("TERM");
		if (term && strcmp(term, "dumb"))
			return 1;
	}
	return 0;
}

int perf_color_default_config(const char *var, const char *value,
			      void *cb __maybe_unused)
{
	if (!strcmp(var, "color.ui")) {
		perf_use_color_default = perf_config_colorbool(var, value, -1);
		return 0;
	}

	return 0;
}

static int __color_vsnprintf(char *bf, size_t size, const char *color,
			     const char *fmt, va_list args, const char *trail)
{
	int r = 0;

	/*
	 * Auto-detect:
	 */
	if (perf_use_color_default < 0) {
		if (isatty(1) || pager_in_use())
			perf_use_color_default = 1;
		else
			perf_use_color_default = 0;
	}

	if (perf_use_color_default && *color)
		r += scnprintf(bf, size, "%s", color);
	r += vscnprintf(bf + r, size - r, fmt, args);
	if (perf_use_color_default && *color)
		r += scnprintf(bf + r, size - r, "%s", PERF_COLOR_RESET);
	if (trail)
		r += scnprintf(bf + r, size - r, "%s", trail);
	return r;
}

/* Colors are not included in return value */
static int __color_vfprintf(FILE *fp, const char *color, const char *fmt,
		va_list args)
{
	int r = 0;

	/*
	 * Auto-detect:
	 */
	if (perf_use_color_default < 0) {
		if (isatty(fileno(fp)) || pager_in_use())
			perf_use_color_default = 1;
		else
			perf_use_color_default = 0;
	}

	if (perf_use_color_default && *color)
		fprintf(fp, "%s", color);
	r += vfprintf(fp, fmt, args);
	if (perf_use_color_default && *color)
		fprintf(fp, "%s", PERF_COLOR_RESET);
	return r;
}

int color_vsnprintf(char *bf, size_t size, const char *color,
		    const char *fmt, va_list args)
{
	return __color_vsnprintf(bf, size, color, fmt, args, NULL);
}

int color_vfprintf(FILE *fp, const char *color, const char *fmt, va_list args)
{
	return __color_vfprintf(fp, color, fmt, args);
}

int color_snprintf(char *bf, size_t size, const char *color,
		   const char *fmt, ...)
{
	va_list args;
	int r;

	va_start(args, fmt);
	r = color_vsnprintf(bf, size, color, fmt, args);
	va_end(args);
	return r;
}

int color_fprintf(FILE *fp, const char *color, const char *fmt, ...)
{
	va_list args;
	int r;

	va_start(args, fmt);
	r = color_vfprintf(fp, color, fmt, args);
	va_end(args);
	return r;
}

/*
 * This function splits the buffer by newlines and colors the lines individually.
 *
 * Returns 0 on success.
 */
int color_fwrite_lines(FILE *fp, const char *color,
		size_t count, const char *buf)
{
	if (!*color)
		return fwrite(buf, count, 1, fp) != 1;

	while (count) {
		char *p = memchr(buf, '\n', count);

		if (p != buf && (fputs(color, fp) < 0 ||
				fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 ||
				fputs(PERF_COLOR_RESET, fp) < 0))
			return -1;
		if (!p)
			return 0;
		if (fputc('\n', fp) < 0)
			return -1;
		count -= p + 1 - buf;
		buf = p + 1;
	}
	return 0;
}

const char *get_percent_color(double percent)
{
	const char *color = PERF_COLOR_NORMAL;

	/*
	 * We color high-overhead entries in red, mid-overhead
	 * entries in green - and keep the low overhead places
	 * normal:
	 */
	if (fabs(percent) >= MIN_RED)
		color = PERF_COLOR_RED;
	else {
		if (fabs(percent) > MIN_GREEN)
			color = PERF_COLOR_GREEN;
	}
	return color;
}

int percent_color_fprintf(FILE *fp, const char *fmt, double percent)
{
	int r;
	const char *color;

	color = get_percent_color(percent);
	r = color_fprintf(fp, color, fmt, percent);

	return r;
}

int value_color_snprintf(char *bf, size_t size, const char *fmt, double value)
{
	const char *color = get_percent_color(value);
	return color_snprintf(bf, size, color, fmt, value);
}

int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...)
{
	va_list args;
	double percent;

	va_start(args, fmt);
	percent = va_arg(args, double);
	va_end(args);
	return value_color_snprintf(bf, size, fmt, percent);
}

int percent_color_len_snprintf(char *bf, size_t size, const char *fmt, ...)
{
	va_list args;
	int len;
	double percent;
	const char *color;

	va_start(args, fmt);
	len = va_arg(args, int);
	percent = va_arg(args, double);
	va_end(args);

	color = get_percent_color(percent);
	return color_snprintf(bf, size, color, fmt, len, percent);
}
