/*
 * Copyright 2022 Sony Corporation
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <linux/types.h>
#include <sony_panel.h>
#include <debug_impl.h>

#include "data_variation_resolver_client.h"
#include "data_variation_resolver.h"
#include "cJSON.h"

#define PANEL_ID_STRING "Panel ID String"
#define PANEL_LESS_ID "FFFFFFFFFFFFFFFF"
#define PANEL_ID_KEY "PanelID"

static void get_required_attributes(int32_t list_size, const char *list, int32_t attibutes_size, char *attibutes);

void find_data(const char *json_string, int32_t data_name_size, char *data_name)
{
	char list[KEY_MAXSIZE][CHAR_MAXSIZE] = {0};
	char attibutes[KEY_VALUE_NUM][KEY_MAXSIZE][CHAR_MAXSIZE] = {0};
	char *json_string_copy = NULL;

	//data_name NULL check
	if (data_name == NULL) {
		UBOOT_ERROR("data_name NULL\n");
		return;
	}
	memset(data_name, 0, data_name_size);

	//json_string NULL check
	if (json_string == NULL) {
		UBOOT_ERROR("json_string NULL\n");
		return;
	}

	json_string_copy = (char *)malloc(strlen(json_string) + 1);
	if (json_string_copy == NULL) {
		UBOOT_ERROR("json_string_copy malloc error\n");
		return;
	}
	memcpy(json_string_copy, json_string, strlen(json_string) + 1);

	//Delete Copyright description of Json String
	cJSON_Minify(json_string_copy);

	//Get Key
	get_require_attribute_keys(json_string_copy, sizeof(list), &list[0][0]);
	if (strnlen(list[0], CHAR_MAXSIZE) == 0) {
		UBOOT_ERROR("get_require_attribute_keys Error\n");
		free(json_string_copy);
		return;
	}

	//Get Value
	get_required_attributes(sizeof(list), &list[0][0], sizeof(attibutes), &attibutes[0][0][0]);

	//Get dataname
	get_corresponding_data_variation(json_string_copy, sizeof(attibutes), &attibutes[0][0][0], data_name_size, data_name);
	if (strnlen(data_name, data_name_size) == 0) {
		UBOOT_ERROR("get_corresponding_data_variation Error\n");
		free(json_string_copy);
		return;
	}
	free(json_string_copy);
}

static void get_required_attributes(int32_t list_size, const char *list, int32_t attibutes_size, char *attibutes)
{

	char panel_id_str[CHAR_MAXSIZE] = {0};
	char product_config_str[CHAR_MAXSIZE] = {0};
	uint32_t key_value_cnt = 0;
	uint32_t key_strlen = 0;
	uint32_t value_strlen = 0;
	int32_t ret;
	char list_copy[KEY_MAXSIZE][CHAR_MAXSIZE] = {0};
	char value_store[KEY_VALUE_NUM][KEY_MAXSIZE][CHAR_MAXSIZE] = {0};

	//attibutes NULL check
	if (attibutes == NULL) {
		UBOOT_ERROR("attibutes NULL\n");
		return;
	}
	memset(attibutes, 0, attibutes_size);

	//list NULL check
	if (list == NULL) {
		UBOOT_ERROR("list NULL\n");
		return;
	}

	if (list_size != sizeof(list_copy)) {
		UBOOT_ERROR("list_size and list_copy size not match\n");
		return;
	}
	memcpy(list_copy, list, list_size);

	if (attibutes_size != sizeof(value_store)) {
		UBOOT_ERROR("attibutes_size and value_store size not match\n");
		return;
	}

	//Put Key and Value in the attibutes
	for (key_value_cnt = 0; key_value_cnt < KEY_MAXSIZE; key_value_cnt++) {
		//Put Key in the attibutes
		key_strlen = strnlen(list_copy[key_value_cnt], CHAR_MAXSIZE);
		if (key_strlen == 0)
			break;
		strncpy(value_store[KEY_IDX][key_value_cnt], list_copy[key_value_cnt], key_strlen);

		//Get the Value of the Key
		if (strcmp(list_copy[key_value_cnt], PANEL_ID_STRING) == 0) {
			//Get Panel_ID
			ret = paneldet_getPanelId(panel_id_str);
			if (ret != 0) {
				UBOOT_ERROR("paneldet_getPanelId Error\n");
				memset(value_store[VALUE_IDX], 0, sizeof(value_store[VALUE_IDX]));
				break;
			}
			if (strcmp(panel_id_str, PANEL_LESS_ID) == 0) {
				memset(panel_id_str, 0, sizeof(panel_id_str));
				ret = get_product_config_value(PANEL_ID_KEY, panel_id_str);
				if (ret != 0) {
					UBOOT_ERROR("get_product_config_value  panel_id Error\n");
					memset(value_store[VALUE_IDX], 0, sizeof(value_store[VALUE_IDX]));
					break;
				}
			}
			value_strlen = strnlen(panel_id_str, CHAR_MAXSIZE);
			strncpy(value_store[VALUE_IDX][key_value_cnt], panel_id_str, value_strlen);
		} else {
			//Get Product Config
			memset(product_config_str, 0, sizeof(product_config_str));
			ret = get_product_config_value(list_copy[key_value_cnt], product_config_str);

			//Put Product Config in the attibutes
			value_strlen = strnlen(product_config_str, CHAR_MAXSIZE);
			strncpy(value_store[VALUE_IDX][key_value_cnt], product_config_str, value_strlen);
		}
	}
	memcpy(attibutes, value_store, attibutes_size);
}
