// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * Copyright (c) 2020 MediaTek Inc.
 */

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include "mtk_dmx_common.h"
#include "mtk_dmx_log.h"

//-------------------------------------------------------------------------------------------------
//  Debug Constants and Macros
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Constants
//-------------------------------------------------------------------------------------------------
#define FTRACE_DEBUG_TYPE_NAME_MAX (32)

//-------------------------------------------------------------------------------------------------
//  Macros
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Structs and Enums
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Variables
//-------------------------------------------------------------------------------------------------
static bool g_ftrace_debug_enables[MTK_DMX_FTRACE_DEBUG_TYPE_MAX] = { false };

static const char g_ftrace_debug_type_names
	[MTK_DMX_FTRACE_DEBUG_TYPE_MAX][FTRACE_DEBUG_TYPE_NAME_MAX] = {
	MTK_DMX_FTAG0, // PCR
	MTK_DMX_FTAG1, // SECT
	MTK_DMX_FTAG2, // TEMI
	MTK_DMX_FTAG3, // FIQ
};

//-------------------------------------------------------------------------------------------------
//  Internal Functions
//-------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------------
//  Public Functions
//-------------------------------------------------------------------------------------------------
bool mtk_dmx_ftrace_get_debug_enable(enum mtk_dmx_ftrace_debug_type ftrace_debug_type)
{
	if (MTK_DMX_IN_RANGE(
		ftrace_debug_type,
		MTK_DMX_FTRACE_DEBUG_TYPE_MIN,
		MTK_DMX_FTRACE_DEBUG_TYPE_MAX - MTK_DMX_FTRACE_DEBUG_TYPE_MIN))
		return g_ftrace_debug_enables[ftrace_debug_type];

	return false;
}

int mtk_dmx_ftrace_get_debug_enable_by_name(
		const char *ftrace_debug_type_name,
		bool *is_enabled)
{
	enum mtk_dmx_ftrace_debug_type ftrace_debug_type = MTK_DMX_FTRACE_DEBUG_TYPE_MAX;

	ftrace_debug_type = mtk_dmx_ftrace_convert_to_ftrace_debug_type(ftrace_debug_type_name);
	if (ftrace_debug_type >= MTK_DMX_FTRACE_DEBUG_TYPE_MAX) {
		MTK_DMX_ERR("ftrace_debug_type_name %s is not found\n", ftrace_debug_type_name);

		return -EINVAL;
	}
	if (MTK_DMX_VERIFY(is_enabled == NULL))
		return -EINVAL;

	*is_enabled = mtk_dmx_ftrace_get_debug_enable(ftrace_debug_type);

	return 0;
}

int mtk_dmx_ftrace_set_debug_enable_by_name(
		const char *ftrace_debug_type_name,
		bool is_enabled)
{
	enum mtk_dmx_ftrace_debug_type ftrace_debug_type = MTK_DMX_FTRACE_DEBUG_TYPE_MAX;

	ftrace_debug_type = mtk_dmx_ftrace_convert_to_ftrace_debug_type(ftrace_debug_type_name);
	if (ftrace_debug_type >= MTK_DMX_FTRACE_DEBUG_TYPE_MAX) {
		MTK_DMX_ERR("ftrace_debug_type_name not found\n");

		return -EINVAL;
	}

	g_ftrace_debug_enables[ftrace_debug_type] = is_enabled;

	return 0;
}

enum mtk_dmx_ftrace_debug_type mtk_dmx_ftrace_convert_to_ftrace_debug_type(
		const char *ftrace_debug_type_name)
{
	enum mtk_dmx_ftrace_debug_type ftrace_debug_type = MTK_DMX_FTRACE_DEBUG_TYPE_MAX;

	if (MTK_DMX_VERIFY(ftrace_debug_type_name == NULL))
		return MTK_DMX_FTRACE_DEBUG_TYPE_MAX;

	for (ftrace_debug_type = MTK_DMX_FTRACE_DEBUG_TYPE_MIN;
		ftrace_debug_type < MTK_DMX_FTRACE_DEBUG_TYPE_MAX;
		ftrace_debug_type++)
		if (strncmp(
			g_ftrace_debug_type_names[ftrace_debug_type],
			ftrace_debug_type_name,
			strlen(g_ftrace_debug_type_names[ftrace_debug_type])) == 0)
			break;

	return ftrace_debug_type;
}


const char *mtk_dmx_ftrace_get_ftrace_debug_type_name(
		enum mtk_dmx_ftrace_debug_type ftrace_debug_type)
{
	static char unknown_enum[MTK_DMX_LOG_UNKNOWN_ENUM_SIZE] = { 0 };
	int tmp_ret = 0;

	if (MTK_DMX_IN_RANGE(
		ftrace_debug_type,
		MTK_DMX_FTRACE_DEBUG_TYPE_MIN,
		MTK_DMX_FTRACE_DEBUG_TYPE_MAX - MTK_DMX_FTRACE_DEBUG_TYPE_MIN))
		return g_ftrace_debug_type_names[ftrace_debug_type];

	memset(unknown_enum, 0, sizeof(unknown_enum));

	tmp_ret = snprintf(unknown_enum,
			sizeof(unknown_enum),
			"UNKNOWN FTRACE DEBUG TYPE 0x%x",
			ftrace_debug_type);
	if (tmp_ret >= sizeof(unknown_enum))
		MTK_DMX_WARN("unknown_enum is truncated\n");
	else if (tmp_ret < 0)
		MTK_DMX_WARN("snprintf is failed. error %d\n", tmp_ret);

	return unknown_enum;
}
