/**
 * Copyright © 2016 Google Inc.
 * Copyright © 2016 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "gpio_configs.h"
#include "gpio_json.h"
#include <cjson/cJSON.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>


/**
 * Loads the GPIO information into the gpios->power_gpio structure
 * from the JSON.
 *
 * @param gpios - the structure where GpioConfigs.power_gpio will
 *                be filled in.
 * @param gpio_configs - cJSON pointer to the GPIO JSON
 */
void read_power_gpios(GpioConfigs* gpios, const cJSON* gpio_configs)
{
	size_t i = 0;

	const cJSON* power_config = cJSON_GetObjectItem(
			gpio_configs, "power_config");
	g_assert(power_config != NULL);

	/* PGOOD - required */

	const cJSON* pgood = cJSON_GetObjectItem(power_config, "power_good_in");
	g_assert(pgood != NULL);

	gpios->power_gpio.power_good_in.name = g_strdup(pgood->valuestring);

	g_print("Power GPIO power good input: %s\n",
			gpios->power_gpio.power_good_in.name);

	/* Latch out - optional */

	const cJSON* latch = cJSON_GetObjectItem(power_config, "latch_out");
	if (latch != NULL)
	{
		gpios->power_gpio.latch_out.name = g_strdup(latch->valuestring);
		g_print("Power GPIO latch output: %s\n",
				gpios->power_gpio.latch_out.name);
	}
	else
	{
		//Must be NULL if not there
		gpios->power_gpio.latch_out.name = NULL;
	}

	/* Power Up Outs - required */

	const cJSON* power_up_outs = cJSON_GetObjectItem(
			power_config, "power_up_outs");
	g_assert(power_up_outs != NULL);

	gpios->power_gpio.num_power_up_outs = cJSON_GetArraySize(power_up_outs);
	g_print("Power GPIO %zu power_up outputs\n",
			gpios->power_gpio.num_power_up_outs);

	if (gpios->power_gpio.num_power_up_outs != 0)
	{
		gpios->power_gpio.power_up_outs =
			g_malloc0_n(gpios->power_gpio.num_power_up_outs, sizeof(GPIO));
		gpios->power_gpio.power_up_pols =
			g_malloc0_n(gpios->power_gpio.num_power_up_outs, sizeof(gboolean));

		const cJSON* power_out;
		cJSON_ArrayForEach(power_out, power_up_outs)
		{
			cJSON* name = cJSON_GetObjectItem(power_out, "name");
			g_assert(name != NULL);
			gpios->power_gpio.power_up_outs[i].name =
				g_strdup(name->valuestring);

			const cJSON* polarity = cJSON_GetObjectItem(power_out, "polarity");
			g_assert(polarity != NULL);
			gpios->power_gpio.power_up_pols[i] = polarity->valueint;

			g_print("Power GPIO power_up[%d] = %s active %s\n",
					i, gpios->power_gpio.power_up_outs[i].name,
					gpios->power_gpio.power_up_pols[i] ? "HIGH" : "LOW");
			i++;
		}
	}

	/* Resets - optional */

	const cJSON* reset_outs = cJSON_GetObjectItem(power_config, "reset_outs");
	gpios->power_gpio.num_reset_outs = cJSON_GetArraySize(reset_outs);

	g_print("Power GPIO %zu reset outputs\n",
			gpios->power_gpio.num_reset_outs);

	if (gpios->power_gpio.num_reset_outs != 0)
	{
		gpios->power_gpio.reset_outs =
			g_malloc0_n(gpios->power_gpio.num_reset_outs, sizeof(GPIO));
		gpios->power_gpio.reset_pols =
			g_malloc0_n(gpios->power_gpio.num_reset_outs, sizeof(gboolean));

		i = 0;
		const cJSON* reset_out;
		cJSON_ArrayForEach(reset_out, reset_outs)
		{
			cJSON* name = cJSON_GetObjectItem(reset_out, "name");
			g_assert(name != NULL);
			gpios->power_gpio.reset_outs[i].name = g_strdup(name->valuestring);

			const cJSON* polarity = cJSON_GetObjectItem(reset_out, "polarity");
			g_assert(polarity != NULL);
			gpios->power_gpio.reset_pols[i] = polarity->valueint;

			g_print("Power GPIO reset[%d] = %s active %s\n", i,
					gpios->power_gpio.reset_outs[i].name,
					gpios->power_gpio.reset_pols[i] ? "HIGH" : "LOW");
			i++;
		}
	}

	/* PCI Resets - optional */

	const cJSON* pci_reset_outs = cJSON_GetObjectItem(
			power_config, "pci_reset_outs");

	gpios->power_gpio.num_pci_reset_outs =
		cJSON_GetArraySize(pci_reset_outs);

	g_print("Power GPIO %zd pci reset outputs\n",
			gpios->power_gpio.num_pci_reset_outs);

	if (gpios->power_gpio.num_pci_reset_outs != 0)
	{
		gpios->power_gpio.pci_reset_outs =
			g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(GPIO));
		gpios->power_gpio.pci_reset_pols =
			g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(gboolean));
		gpios->power_gpio.pci_reset_holds =
			g_malloc0_n(gpios->power_gpio.num_pci_reset_outs, sizeof(gboolean));

		i = 0;
		const cJSON* pci_reset_out;
		cJSON_ArrayForEach(pci_reset_out, pci_reset_outs)
		{
			cJSON* name = cJSON_GetObjectItem(pci_reset_out, "name");
			g_assert(name != NULL);
            gpios->power_gpio.pci_reset_outs[i].name =
                g_strdup(name->valuestring);

			const cJSON* polarity = cJSON_GetObjectItem(
                    pci_reset_out, "polarity");
			g_assert(polarity != NULL);
			gpios->power_gpio.pci_reset_pols[i] = polarity->valueint;

			const cJSON* hold = cJSON_GetObjectItem(pci_reset_out, "hold");
			g_assert(hold != NULL);
			gpios->power_gpio.pci_reset_holds[i] = polarity->valueint;

			g_print("Power GPIO pci reset[%d] = %s active %s, hold %s\n", i,
					gpios->power_gpio.pci_reset_outs[i].name,
					gpios->power_gpio.pci_reset_pols[i] ? "HIGH" : "LOW",
					gpios->power_gpio.pci_reset_holds[i] ? "Yes" : "No");
			i++;
		}
	}
}

gboolean read_gpios(GDBusConnection *connection, GpioConfigs *gpios)
{
	cJSON* json = load_json();
	if (json == NULL)
	{
		return FALSE;
	}

	const cJSON* configs = cJSON_GetObjectItem(json, "gpio_configs");
	g_assert(configs != NULL);

	read_power_gpios(gpios, configs);

	cJSON_Delete(json);
	return TRUE;
}

void free_gpios(GpioConfigs *gpios) {
	int i;
	g_free(gpios->power_gpio.latch_out.name);
	g_free(gpios->power_gpio.power_good_in.name);
	for(i = 0; i < gpios->power_gpio.num_power_up_outs; i++) {
		g_free(gpios->power_gpio.power_up_outs[i].name);
	}
	g_free(gpios->power_gpio.power_up_outs);
	g_free(gpios->power_gpio.power_up_pols);
	for(i = 0; i < gpios->power_gpio.num_reset_outs; i++) {
		g_free(gpios->power_gpio.reset_outs[i].name);
	}
	g_free(gpios->power_gpio.reset_outs);
	g_free(gpios->power_gpio.reset_pols);
	for(i = 0; i < gpios->power_gpio.num_pci_reset_outs; i++) {
		g_free(gpios->power_gpio.pci_reset_outs[i].name);
	}
	g_free(gpios->power_gpio.pci_reset_outs);
	g_free(gpios->power_gpio.pci_reset_pols);
	g_free(gpios->power_gpio.pci_reset_holds);
}
