#define _GNU_SOURCE

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <argp.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <dirent.h>
#include "openbmc_intf.h"
#include "gpio.h"
#include "gpio_json.h"

#include <sys/ioctl.h>
#include <linux/gpio.h>

#define GPIO_PORT_OFFSET 8
#define GPIO_BASE_PATH "/sys/class/gpio"

cJSON* gpio_json = NULL;

int gpio_write(GPIO* gpio, uint8_t value)
{
	g_assert (gpio != NULL);
	struct gpiohandle_data data;
	memset(&data, 0, sizeof(data));
	data.values[0] = value;

	if (gpio->fd <= 0)
	{
		return GPIO_ERROR;
	}

	if (ioctl(gpio->fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data) < 0)
	{
		return GPIO_WRITE_ERROR;
	}

	return GPIO_OK;
}

int gpio_read(GPIO* gpio, uint8_t *value)
{
	g_assert (gpio != NULL);
	struct gpiohandle_data data;
	memset(&data, 0, sizeof(data));

	if (gpio->fd <= 0)
	{
		return GPIO_ERROR;
	}

	if (ioctl(gpio->fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data) < 0)
	{
		return GPIO_READ_ERROR;
	}

	*value = data.values[0];

	return GPIO_OK;
}

/**
 * Determine the GPIO base number for the system.  It is found in
 * the 'base' file in the /sys/class/gpio/gpiochipX/ directory where the
 * /sys/class/gpio/gpiochipX/label file has a '1e780000.gpio' in it.
 *
 * Note: This method is ASPEED specific.  Could add support for
 * additional SOCs in the future.
 *
 * @return int - the GPIO base number, or < 0 if not found
 */
int get_gpio_base()
{
	int gpio_base = -1;

	DIR* dir = opendir(GPIO_BASE_PATH);
	if (dir == NULL)
	{
		fprintf(stderr, "Unable to open directory %s\n",
				GPIO_BASE_PATH);
		return -1;
	}

	struct dirent* entry;
	while ((entry = readdir(dir)) != NULL)
	{

		/* Look in the gpiochip<X> directories for a file called 'label' */
		/* that contains '1e780000.gpio', then in that directory read */
		/* the GPIO base out of the 'base' file. */

		if (strncmp(entry->d_name, "gpiochip", 8) != 0)
		{
			continue;
		}

		gboolean is_bmc = FALSE;
		char* label_name;
		int rc = asprintf(&label_name, "%s/%s/label",
				GPIO_BASE_PATH, entry->d_name);

		if (!rc)
		{
			continue;
		}

		FILE* fd = fopen(label_name, "r");
		free(label_name);

		if (!fd)
		{
			continue;
		}

		char label[14];
		if (fgets(label, 14, fd) != NULL)
		{
			if (strcmp(label, "1e780000.gpio") == 0)
			{
				is_bmc = TRUE;
			}
		}
		fclose(fd);

		if (!is_bmc)
		{
			continue;
		}

		char* base_name;
		rc = asprintf(&base_name, "%s/%s/base",
				GPIO_BASE_PATH, entry->d_name);

		if (!rc)
		{
			continue;
		}

		fd = fopen(base_name, "r");
		free(base_name);

		if (!fd)
		{
			continue;
		}

		if (fscanf(fd, "%d", &gpio_base) != 1)
		{
			gpio_base = -1;
		}
		fclose(fd);

		/* We found the right file. No need to continue. */
		break;
	}
	closedir(dir);

	if (gpio_base == -1)
	{
		fprintf(stderr, "Could not find GPIO base\n");
	}

	return gpio_base;
}

/**
 * Converts the GPIO port/offset nomenclature value
 * to a number.  Supports the ASPEED method where
 * num = base + (port * 8) + offset, and the port is an
 * A-Z character that converts to 0 to 25.  The base
 * is obtained form the hardware.
 *
 * For example: "A5" -> 5,  "Z7" -> 207
 *
 * @param[in] gpio - the GPIO name
 *
 * @return int - the GPIO number or < 0 if not found
 */
int convert_gpio_to_num(const char* gpio)
{
	size_t len = strlen(gpio);
	if (len < 2)
	{
		fprintf(stderr, "Invalid GPIO name %s\n", gpio);
		return -1;
	}

	/* Read the offset from the last character */
	if (!isdigit(gpio[len-1]))
	{
		fprintf(stderr, "Invalid GPIO offset in GPIO %s\n", gpio);
		return -1;
	}

	int offset = gpio[len-1] - '0';

	/* Read the port from the second to last character */
	if (!isalpha(gpio[len-2]))
	{
		fprintf(stderr, "Invalid GPIO port in GPIO %s\n", gpio);
		return -1;
	}
	int port = toupper(gpio[len-2]) - 'A';

	/* Check for a 2 character port, like AA */
	if ((len == 3) && isalpha(gpio[len-3]))
	{
		port += 26 * (toupper(gpio[len-3]) - 'A' + 1);
	}

	return (port * GPIO_PORT_OFFSET) + offset;
}

/**
 * Returns the cJSON pointer to the GPIO definition
 * for the GPIO passed in.
 *
 * @param[in] gpio_name - the GPIO name, like BMC_POWER_UP
 *
 * @return cJSON* - pointer to the cJSON object or NULL
 *				  if not found.
 */
cJSON* get_gpio_def(const char* gpio_name)
{
	if (gpio_json == NULL)
	{
		gpio_json = load_json();
		if (gpio_json == NULL)
		{
			return NULL;
		}
	}

	cJSON* gpio_defs = cJSON_GetObjectItem(gpio_json, "gpio_definitions");
	g_assert(gpio_defs != NULL);

	cJSON* def;
	cJSON_ArrayForEach(def, gpio_defs)
	{
		cJSON* name = cJSON_GetObjectItem(def, "name");
		g_assert(name != NULL);

		if (strcmp(name->valuestring, gpio_name) == 0)
		{
			return def;
		}
	}
	return NULL;
}

/**
 * Frees the gpio_json memory
 *
 * Can be called once when callers are done calling making calls
 * to gpio_init() so that the JSON only needs to be loaded once.
 */
void gpio_inits_done()
{
	if (gpio_json != NULL)
	{
		cJSON_Delete(gpio_json);
		gpio_json = NULL;
	}
}

/**
 * Fills in the dev, direction, and num elements in
 * the GPIO structure.
 *
 * @param gpio - the GPIO structure to fill in
 *
 * @return GPIO_OK if successful
 */
int gpio_get_params(GPIO* gpio)
{
	gpio->dev = g_strdup(GPIO_BASE_PATH);

	const cJSON* def = get_gpio_def(gpio->name);
	if (def == NULL)
	{
		fprintf(stderr, "Unable to find GPIO %s in the JSON\n",
				gpio->name);
		return GPIO_LOOKUP_ERROR;
	}

	const cJSON* dir = cJSON_GetObjectItem(def, "direction");
	g_assert(dir != NULL);
	gpio->direction = g_strdup(dir->valuestring);

	/* Must use either 'num', like 87, or 'pin', like "A5" */
	const cJSON* num = cJSON_GetObjectItem(def, "num");
	if ((num != NULL) && cJSON_IsNumber(num))
	{
		gpio->num = num->valueint;
	}
	else
	{
		const cJSON* pin = cJSON_GetObjectItem(def, "pin");
		g_assert(pin != NULL);

		int pin_id = convert_gpio_to_num(pin->valuestring);
		if (pin_id < 0)
		{
			return GPIO_LOOKUP_ERROR;
		}
		gpio->num = (size_t) pin_id;
	}
	// TODO: For the purposes of skeleton and the projects that use it,
	// it should be safe to assume this will always be 0. Eventually skeleton
	// should be going away, but if the need arises before then this may need
	// to be updated to handle non-zero cases.
	gpio->chip_id = 0;
	return GPIO_OK;
}

int gpio_open(GPIO* gpio, uint8_t default_value)
{
	g_assert (gpio != NULL);

	char buf[255];
	sprintf(buf, "/dev/gpiochip%d", gpio->chip_id);
	gpio->fd = open(buf, 0);
	if (gpio->fd == -1)
	{
		return GPIO_OPEN_ERROR;
	}

	struct gpiohandle_request req;
	memset(&req, 0, sizeof(req));
	strncpy(req.consumer_label, "skeleton-gpio",  sizeof(req.consumer_label));

	// open gpio for writing or reading
	if (gpio->direction == NULL)
	{
		gpio_close(gpio);
		return GPIO_OPEN_ERROR;
	}
	req.flags = (strcmp(gpio->direction,"in") == 0) ? GPIOHANDLE_REQUEST_INPUT
								: GPIOHANDLE_REQUEST_OUTPUT;

	req.lineoffsets[0] = gpio->num;
	req.lines = 1;

	if (strcmp(gpio->direction,"out") == 0)
	{
		req.default_values[0] = default_value;
	}

	int rc = ioctl(gpio->fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
	if (rc < 0)
	{
		gpio_close(gpio);
		return GPIO_OPEN_ERROR;
	}
	gpio_close(gpio);
	gpio->fd = req.fd;

	return GPIO_OK;
}

void gpio_close(GPIO* gpio)
{
	if(gpio->fd < 0)
		return;

	close(gpio->fd);
	gpio->fd = -1;
}
