/*
 * Copyright (C) 2005-2009 Alex Murray <murray.alex@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */

#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif /* HAVE_STDIO_H */

#include <glib.h>
#include <glib/gi18n.h>
#include "i2c-sys-plugin.h"

const gchar *plugin_name = "i2c-sys";

#define I2C_SYS_BASE_DIR "/sys"

enum {
    I2C_SYS_DEVICE_FILE_OPEN_ERROR,
    I2C_SYS_DEVICE_FILE_READ_ERROR
};

static void i2c_sys_plugin_add_sensor(GList **sensors, const gchar *path) {
    gchar *filename;
    gchar *id;
    gchar *label;
    gboolean enable;
    guint sensor_type;
    IconType icon_type = GENERIC_ICON;

    filename = g_path_get_basename(path);

    /* setup temp2 as CPU sensor and enable it */
    if (g_ascii_strcasecmp(filename, "temp2_input") == 0) {
        id = g_strndup(filename, 5);
        label = g_strdup(_("CPU"));
        sensor_type = TEMP_SENSOR;
        enable = TRUE;
        icon_type = CPU_ICON;
    } else {
        switch(filename[0]) {
            case 'c':    /* either current or cpu?_vid sensor */
                if (filename[1] == 'u') { /* currents are curr?_input */
                    id = g_strndup(filename, 5);
                    label = g_strndup(filename, 5);
                    sensor_type = CURRENT_SENSOR;
                } else { /* cpu_vid is cpu?_vid */
                    id = g_strdup(filename);
                    label = g_strdup(filename);
                    sensor_type = VOLTAGE_SENSOR;
                }
                break;

            case 'f':    /* fans are "fan?_input" */
                id = g_strndup(filename, 4);
                label = g_strndup(filename, 4);
                sensor_type = FAN_SENSOR;
                icon_type = FAN_ICON;
                break;

            case 't':    /* temps are "temp?_input" */
                id = g_strndup(filename, 5);
                label = g_strndup(filename, 5);
                sensor_type = TEMP_SENSOR;
                break;

            case 'i':    /* voltages are "in?_input" */
                id = g_strndup(filename, 3);
                label = g_strndup(filename, 3);
                sensor_type = VOLTAGE_SENSOR;
                break;

            default:
                /* SHOULDN'T BE ABLE * TO GET HERE!! */
                g_warning("filename:\"%s\" begins with a charater that is not covered by this switch statement... not adding sensor", filename);
                g_free(filename);
                g_free(id);
                g_free(label);

                return;
        }

        /* disable all other sensors */
        enable = FALSE;
    }

    sensors_applet_plugin_add_sensor(sensors,
                                         path,
                                         id,
                                         label,
                                         sensor_type,
                                         enable,
                                         icon_type,
                                         DEFAULT_GRAPH_COLOR);

    g_free(filename);
    g_free(id);
    g_free(label);
}

static void i2c_sys_plugin_test_sensor(GList **sensors, const gchar *path) {
gchar *filename;

filename = g_path_get_basename(path);

if ((g_str_has_suffix(filename, "_input") &&
    (g_str_has_prefix(filename, "temp") ||
    g_str_has_prefix(filename, "fan") ||
    g_str_has_prefix(filename, "curr") ||
    g_str_has_prefix(filename, "in"))) ||
    (g_str_has_prefix(filename, "cpu") &&
    (g_str_has_suffix(filename, "_vid")))) {

    i2c_sys_plugin_add_sensor(sensors, path);
}

    g_free(filename);
}


/* to be called to setup for sys sensors */
static GList *i2c_sys_plugin_init(void) {
    GList *sensors = NULL;

    /* call function to recursively look for sensors
       starting at the defined base directory */
    sensors_applet_plugin_find_sensors(&sensors,
                                       I2C_SYS_BASE_DIR,
                                       i2c_sys_plugin_test_sensor);
    return sensors;
}

static gdouble i2c_sys_plugin_get_sensor_value(const gchar *path,
                                               const gchar *id,
                                               SensorType type,
                                               GError **error) {

    /* to open and access the value of each sensor */
    FILE *fp;
    gfloat sensor_value;

    if (NULL == (fp = fopen(path, "r"))) {
        g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_SYS_DEVICE_FILE_OPEN_ERROR, "Error opening sensor device file %s", path);
        return -1.0;
    }

    if (fscanf(fp, "%f", &sensor_value) != 1) {
        g_set_error(error, SENSORS_APPLET_PLUGIN_ERROR, I2C_SYS_DEVICE_FILE_READ_ERROR, "Error reading from sensor device file %s", path);
        fclose(fp);
        return -1.0;
    }
    fclose(fp);

    if (type != FAN_SENSOR) {
        sensor_value /= 1000.0;
    }

    return (gdouble)sensor_value;
}

const gchar *sensors_applet_plugin_name(void)
{
    return plugin_name;
}

GList *sensors_applet_plugin_init(void)
{
    return i2c_sys_plugin_init();
}

gdouble sensors_applet_plugin_get_sensor_value(const gchar *path,
                                                const gchar *id,
                                                SensorType type,
                                                GError **error) {

    return i2c_sys_plugin_get_sensor_value(path, id, type, error);
}
