/**
 * 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 <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <string.h>
#include <getopt.h>
#include <systemd/sd-bus.h>

#define DBUS_MAX_NAME_LEN 256

const char *objectmapper_service_name =  "xyz.openbmc_project.ObjectMapper";
const char *objectmapper_object_name  =  "/xyz/openbmc_project/object_mapper";
const char *objectmapper_intf_name    =  "xyz.openbmc_project.ObjectMapper";

typedef struct {
	int fan_num;
	int cpu_num;
	int core_num;
	int dimm_num;
	sd_bus *bus;
	char sensor_service[DBUS_MAX_NAME_LEN];
	char inventory_service[DBUS_MAX_NAME_LEN];
} fan_info_t;

/* Get an object's bus name from ObjectMapper */
int get_connection(sd_bus *bus, char *connection, const char *obj_path)
{
	sd_bus_error bus_error = SD_BUS_ERROR_NULL;
	sd_bus_message *m = NULL;
	char *temp_buf = NULL, *intf = NULL;
	int rc;

	rc = sd_bus_call_method(bus,
				objectmapper_service_name,
				objectmapper_object_name,
				objectmapper_intf_name,
				"GetObject",
				&bus_error,
				&m,
				"s",
				obj_path);
	if (rc < 0) {
		fprintf(stderr,
			"Failed to GetObject: %s\n", bus_error.message);
		goto finish;
	}

	/* Get the key, aka, the bus name */
	sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf);
	strncpy(connection, temp_buf, DBUS_MAX_NAME_LEN);

finish:
	sd_bus_error_free(&bus_error);
	sd_bus_message_unref(m);
	sd_bus_flush(bus);

	return rc;
}


int set_dbus_sensor(sd_bus *bus, const char *obj_path, int val)
{
	char connection[DBUS_MAX_NAME_LEN];
	sd_bus_error bus_error = SD_BUS_ERROR_NULL;
	sd_bus_message *response = NULL;
	int rc;

	if (!bus || !obj_path)
		return -1;

	rc = get_connection(bus, connection, obj_path);
	if (rc < 0) {
		fprintf(stderr,
			"fanctl: Failed to get bus name for %s\n", obj_path);
		goto finish;
	}

	rc = sd_bus_call_method(bus,
				connection,
				obj_path,
				"org.openbmc.SensorValue",
				"setValue",
				&bus_error,
				&response,
				"i",
				val);
	if (rc < 0)
		fprintf(stderr,
			"fanctl: Failed to set sensor %s:[%s]\n",
			obj_path, strerror(-rc));

finish:
	sd_bus_error_free(&bus_error);
	sd_bus_message_unref(response);
	sd_bus_flush(bus);

	return rc;
}

/* Read sensor value from "org.openbmc.Sensors" */
int read_dbus_sensor(sd_bus *bus, const char *obj_path)
{
	char connection[DBUS_MAX_NAME_LEN];
	sd_bus_error bus_error = SD_BUS_ERROR_NULL;
	sd_bus_message *response = NULL;
	int rc;
	int val = 0;

	if (!bus || !obj_path)
		return 0;

	rc = get_connection(bus, connection, obj_path);
	if (rc < 0) {
		val = 0;
		fprintf(stderr,
			"fanctl: Failed to get bus name for %s\n", obj_path);
		goto finish;
	}

	rc = sd_bus_call_method(bus,
				connection,
				obj_path,
				"org.openbmc.SensorValue",
				"getValue",
				&bus_error,
				&response,
				NULL);
	if (rc < 0) {
		val = 0;
		fprintf(stderr,
			"fanctl: Failed to read sensor value from %s:[%s]\n",
			obj_path, strerror(-rc));
		goto finish;
	}

	rc = sd_bus_message_read(response, "v","i", &val);
	if (rc < 0) {
		val = 0;
		fprintf(stderr,
			"fanctl: Failed to parse sensor value "
			"response message from %s:[%s]\n",
			obj_path, strerror(-rc));
	}

finish:
	sd_bus_error_free(&bus_error);
	sd_bus_message_unref(response);
	sd_bus_flush(bus);

	return val;
}

/* set fan speed with /org/openbmc/sensors/speed/fan* object */
static int fan_set_speed(sd_bus *bus, int fan_id, uint8_t fan_speed)
{
	char obj_path[DBUS_MAX_NAME_LEN];
	int rc;

	if (!bus)
		return -1;

	snprintf(obj_path, sizeof(obj_path),
		"/org/openbmc/sensors/speed/fan%d", fan_id);
	rc = set_dbus_sensor(bus, obj_path, fan_speed);
	if (rc < 0)
		fprintf(stderr, "fanctl: Failed to set fan[%d] speed[%d]\n",
				fan_id, fan_speed);

	return rc;
}

static int fan_set_max_speed(fan_info_t *info)
{
	int i;
	int rc = -1;

	if (!info)
		return -1;
	for (i = 0; i < info->fan_num; i++) {
		rc = fan_set_speed(info->bus, i, 255);
		if (rc < 0)
			break;
		fprintf(stderr, "fanctl: Set fan%d to max speed\n", i);
	}

	return rc;
}
/*
 * FAN_TACH_OFFSET is specific to Barreleye.
 * Barreleye uses NTC7904D HW Monitor as Fan tachometoer.
 * The 13-bit FANIN value is made up Higer part: [12:5],
 * and Lower part: [4:0], which are read from two sensors.
 * see: https://www.nuvoton.com/resource-files/NCT7904D_Datasheet_V1.44.pdf
 */
#define FAN_TACH_OFFSET 5
static int fan_get_speed(sd_bus *bus, int fan_id)
{
	int fan_tach_H = 0, fan_tach_L = 0;
	char obj_path[DBUS_MAX_NAME_LEN];
	int fan_speed;

	/* get fan tach */
	/* The object path is specific to Barreleye */
	snprintf(obj_path, sizeof(obj_path),
		"/org/openbmc/sensors/tach/fan%dH", fan_id);
	fan_tach_H = read_dbus_sensor(bus, obj_path);
	snprintf(obj_path, sizeof(obj_path),
		"/org/openbmc/sensors/tach/fan%dL", fan_id);
	fan_tach_L = read_dbus_sensor(bus, obj_path);

	/* invalid sensor value is -1 */
	if (fan_tach_H <= 0 || fan_tach_L <= 0)
		fan_speed = 0;
	else
		fan_speed = fan_tach_H << FAN_TACH_OFFSET | fan_tach_L;

	fprintf(stderr, "fan%d speed: %d\n", fan_id, fan_speed);
	return fan_speed;
}

/* set Fan Inventory 'Present' status */
int fan_set_present(sd_bus *bus, int fan_id, int val)
{
	sd_bus_error bus_error = SD_BUS_ERROR_NULL;
	sd_bus_message *response = NULL;
	int rc;
	char obj_path[DBUS_MAX_NAME_LEN];
	char connection[DBUS_MAX_NAME_LEN];

	snprintf(obj_path, sizeof(obj_path),
		"/org/openbmc/inventory/system/chassis/fan%d", fan_id);

	rc = get_connection(bus, connection, obj_path);
	if (rc < 0) {
		fprintf(stderr,
			"fanctl: Failed to get bus name for %s\n", obj_path);
		goto finish;
	}

	rc = sd_bus_call_method(bus,
				connection,
				obj_path,
				"org.openbmc.InventoryItem",
				"setPresent",
				&bus_error,
				&response,
				"s",
				(val == 1 ? "True" : "False"));
	if(rc < 0)
		fprintf(stderr,
			"fanctl: Failed to update fan presence via dbus: %s\n",
			bus_error.message);

	fprintf(stderr, "fanctl: Set fan%d present status to: %s\n",
			fan_id, (val == 1 ? "True" : "False"));

finish:
	sd_bus_error_free(&bus_error);
	sd_bus_message_unref(response);
	sd_bus_flush(bus);

	return rc;
}

/*
 * Update Fan Invertory 'Present' status by first reading fan speed.
 * If fan speed is '0', the fan is considerred not 'Present'.
 */
static int fan_update_present(fan_info_t *info)
{
	int i;
	int rc = -1;
	int fan_speed;

	if (!info)
		return -1;

	for (i = 0; i < info->fan_num; i++) {
		fan_speed = fan_get_speed(info->bus, i);
		if (fan_speed > 0)
			rc = fan_set_present(info->bus, i, 1);
		else
			rc = fan_set_present(info->bus, i, 0);

		if (rc < 0) {
			fprintf(stderr,
				"fanctl: Failed to set fan present status\n");
			break;
		}
	}

	return rc;
}
/*
 * Router function for any FAN operations that come via dbus
 */
static int fan_function_router(sd_bus_message *msg, void *user_data,
		sd_bus_error *ret_error)
{
	/* Generic error reporter. */
	int rc = -1;
	fan_info_t *info = user_data;

	/* Get the Operation. */
	const char *fan_function = sd_bus_message_get_member(msg);
	if (fan_function == NULL) {
		fprintf(stderr, "fanctl: Null FAN function specificed\n");
		return sd_bus_reply_method_return(msg, "i", rc);
	}

	/* Route the user action to appropriate handlers. */
	if ((strcmp(fan_function, "setMax") == 0)) {
		rc = fan_set_max_speed(info);
		return sd_bus_reply_method_return(msg, "i", rc);
	}
	if ((strcmp(fan_function, "updatePresent") == 0)) {
		rc = fan_update_present(info);
		return sd_bus_reply_method_return(msg, "i", rc);
	}

	return sd_bus_reply_method_return(msg, "i", rc);
}

/* Dbus Services offered by this FAN controller */
static const sd_bus_vtable fan_control_vtable[] =
{
	SD_BUS_VTABLE_START(0),
	SD_BUS_METHOD("setMax", "", "i", &fan_function_router,
			SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_METHOD("updatePresent", "", "i", &fan_function_router,
			SD_BUS_VTABLE_UNPRIVILEGED),
	SD_BUS_VTABLE_END,
};

int start_fan_services(fan_info_t *info)
{
	/* Generic error reporter. */
	int rc = -1;
	/* slot where we are offering the FAN dbus service. */
	sd_bus_slot *fan_slot = NULL;
	const char *fan_object = "/org/openbmc/control/fans";

	info->bus = NULL;
	/* Get a hook onto system bus. */
	rc = sd_bus_open_system(&info->bus);
	if (rc < 0) {
		fprintf(stderr,"fanctl: Error opening system bus.\n");
		return rc;
	}

	/* Install the object */
	rc = sd_bus_add_object_vtable(info->bus,
			&fan_slot,
			fan_object, /* object path */
			"org.openbmc.control.Fans", /* interface name */
			fan_control_vtable,
			info);
	if (rc < 0) {
		fprintf(stderr, "fanctl: Failed to add object to dbus: %s\n",
				strerror(-rc));
		return rc;
	}

	/* If we had success in adding the providers, request for a bus name. */
	rc = sd_bus_request_name(info->bus,
			"org.openbmc.control.Fans", 0);
	if (rc < 0) {
		fprintf(stderr, "fanctl: Failed to acquire service name: %s\n",
				strerror(-rc));
		return rc;
	}

	for (;;) {
		/* Process requests */
		rc = sd_bus_process(info->bus, NULL);
		if (rc < 0) {
			fprintf(stderr, "fanctl: Failed to process bus: %s\n",
					strerror(-rc));
			break;
		}
		if (rc > 0) {
			continue;
		}

		rc = sd_bus_wait(info->bus, (uint64_t) - 1);
		if (rc < 0) {
			fprintf(stderr, "fanctl: Failed to wait on bus: %s\n",
				strerror(-rc));
			break;
		}
	}

	sd_bus_slot_unref(fan_slot);
	sd_bus_unref(info->bus);

	return rc;
}

static int str_to_int(char *str)
{
	long val;
	char *temp;

	val = strtol(str, &temp, 10);
	if (temp == str || *temp != '\0' ||
		((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE))
		return -1;
	if (val < 0)
		return -1;

	return (int)val;
}

static int parse_argument(int argc, char **argv, fan_info_t *info)
{
	int c;
	struct option long_options[] =
	{
		{"fan_num",  required_argument, 0, 'f'},
		{"core_num",    required_argument, 0, 'c'},
		{"cpu_num",    required_argument, 0, 'p'},
		{"dimm_num",    required_argument, 0, 'd'},
		{0, 0, 0, 0}
	};

	while (1) {
		c = getopt_long (argc, argv, "c:d:f:p:", long_options, NULL);

		/* Detect the end of the options. */
		if (c == -1)
			break;

		switch (c) {
		case 'f':
			info->fan_num = str_to_int(optarg);
			if (info->fan_num == -1) {
				fprintf(stderr, "fanctl: Wrong fan_num: %s\n", optarg);
				return -1;
			}
			break;
		case 'c':
			info->core_num = str_to_int(optarg);
			if (info->core_num == -1) {
				fprintf(stderr, "fanctl: Wrong core_num: %s\n", optarg);
				return -1;
			}
			break;
		case 'p':
			info->cpu_num = str_to_int(optarg);
			if (info->cpu_num == -1) {
				fprintf(stderr, "fanctl: Wrong cpu_num: %s\n", optarg);
				return -1;
			}
			break;
		case 'd':
			info->dimm_num = str_to_int(optarg);
			if (info->dimm_num == -1) {
				fprintf(stderr, "fanctl: Wrong dimm_num: %s\n", optarg);
				return -1;
			}
			break;
		default:
			fprintf(stderr, "fanctl: Wrong argument\n");
			return -1;
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	int rc = 0;
	fan_info_t fan_info;

	memset(&fan_info, 0, sizeof(fan_info));
	rc = parse_argument(argc, argv, &fan_info);
	if (rc < 0) {
		fprintf(stderr, "fanctl: Error parse argument\n");
		return rc;
	}
	/* This call is not supposed to return. If it does, then an error */
	rc = start_fan_services(&fan_info);
	if (rc < 0) {
		fprintf(stderr, "fanctl: Error starting FAN Services. Exiting");
	}

	return rc;
}
