#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;
		asprintf(&label_name, "%s/%s/label",
				GPIO_BASE_PATH, entry->d_name);

		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;
		asprintf(&base_name, "%s/%s/base",
				GPIO_BASE_PATH, entry->d_name);

		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);

		gpio->num = convert_gpio_to_num(pin->valuestring);
		if (gpio->num < 0)
		{
			return GPIO_LOOKUP_ERROR;
		}
	}
	// 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;
}
