/*
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 * Not a contribution
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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 <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <dirent.h>

#define LOG_TAG "ThermalHAL-UTIL"
#include <utils/Log.h>

#include <hardware/hardware.h>
#include <hardware/thermal.h>
#include "thermal_common.h"

#define MAX_LENGTH    50
#define MAX_PATH      (256)
#define CPU_LABEL      "CPU%d"
#define THERMAL_SYSFS  "/sys/devices/virtual/thermal"
#define TZ_DIR_NAME    "thermal_zone"
#define TZ_DIR_FMT     "thermal_zone%d"
#define THERMAL_TYPE "/sys/devices/virtual/thermal/%s/type"
#define TEMPERATURE_FILE_FORMAT  "/sys/class/thermal/thermal_zone%d/temp"

static char **cpu_label;
static struct vendor_temperature *sensors;
static unsigned int sensor_cnt;

/**
 * Get number of cpus of target.
 *
 * @return number of cpus on success or 0 on error.
 */
size_t get_num_cpus() {
    ALOGD("Entering %s",__func__);
    static int ncpus;

    if (!ncpus) {
        ncpus = (int)sysconf(_SC_NPROCESSORS_CONF);
        if (ncpus < 1)
            ALOGE("%s: Error retrieving number of cores", __func__);
    }
    return ncpus;
}

/**
 * Get cpu label for a given cpu.
 *
 * @param cpu_num: cpu number.
 *
 * @return cpu label string on success or NULL on error.
 */
const char *get_cpu_label(unsigned int cpu_num) {
    ALOGD("Entering %s",__func__);
    unsigned int cpu = 0;

    if (cpu_label == NULL) {
        cpu_label= (char**)calloc(get_num_cpus(), sizeof(char *));
	if (!cpu_label)
		return NULL;
	for(cpu = 0; cpu < get_num_cpus(); cpu++) {
            cpu_label[cpu] = (char *)calloc(sizeof("CPUN"), sizeof(char));
            if(!cpu_label[cpu])
                return NULL;
            snprintf(cpu_label[cpu], sizeof("CPUN"), CPU_LABEL, cpu);
	}
    }
    if(cpu_num >= get_num_cpus())
        return NULL;

    return cpu_label[cpu_num];
}

/**
 * Read data from a target sysfs file.
 *
 * @param path: Absolute path for a file to be read.
 * @param buf: Char buffer to store data from file.
 * @param count: Size of data buffer.
 *
 * @return number of bytes read on success or negative value on error.
 */
int read_line_from_file(const char *path, char *buf, size_t count)
{
    char * fgets_ret;
    FILE * fd;
    int rv;

    fd = fopen(path, "r");
    if (fd == NULL)
        return -1;

    fgets_ret = fgets(buf, (int)count, fd);
    if (NULL != fgets_ret) {
        rv = (int)strlen(buf);
    } else {
        rv = ferror(fd);
    }

    fclose(fd);

    return rv;
}

/**
 * Function to get thermal zone id from sensor name.
 *
 * @param sensor_name: Name of sensor.
 *
 * @return positive integer on success or negative value on error.
 */
static int get_tzn(const char *sensor_name)
{
    DIR *tdir = NULL;
    struct dirent *tdirent = NULL;
    int found = -1;
    int tzn = 0;
    char name[MAX_PATH] = {0};
    char cwd[MAX_PATH] = {0};
    int ret = 0;

    if (!getcwd(cwd, sizeof(cwd)))
        return found;

    /* Change dir to read the entries. Doesnt work otherwise */
    ret = chdir(THERMAL_SYSFS);
    if (ret) {
        ALOGE("Unable to change to %s\n", THERMAL_SYSFS);
        return found;
    }
    tdir = opendir(THERMAL_SYSFS);
    if (!tdir) {
        ALOGE("Unable to open %s\n", THERMAL_SYSFS);
        return found;
    }

    while ((tdirent = readdir(tdir))) {
        char buf[50];
        struct dirent *tzdirent;
        DIR *tzdir = NULL;

        if (strncmp(tdirent->d_name, TZ_DIR_NAME,
            strlen(TZ_DIR_NAME)) != 0)
            continue;

        tzdir = opendir(tdirent->d_name);
        if (!tzdir)
            continue;
        while ((tzdirent = readdir(tzdir))) {
            if (strcmp(tzdirent->d_name, "type"))
                continue;
            snprintf(name, MAX_PATH, THERMAL_TYPE,
                    tdirent->d_name);
            ret = read_line_from_file(name, buf, sizeof(buf));
            if (ret <= 0) {
                ALOGE("%s: sensor name read error for tz:%s\n",
                        __func__, tdirent->d_name);
                break;
            }
            if (buf[ret - 1] == '\n')
                buf[ret - 1] = '\0';
            else
                buf[ret] = '\0';

            if (!strcmp(buf, sensor_name)) {
                found = 1;
		break;
            }
        }
        closedir(tzdir);
        if (found == 1)
            break;
    }

    if (found == 1) {
        sscanf(tdirent->d_name, TZ_DIR_FMT, &tzn);
        ALOGD("Sensor %s found at tz: %d\n",
                sensor_name, tzn);
        found = tzn;
    }

    closedir(tdir);
    /* Restore current working dir */
    ret = chdir(cwd);

    return found;
}

/**
 * Helper function for sensor intialization.
 *
 * @param v_sen_t: pointer to a sensor static config.
 * @param sensor: pointer to a sensor vendor_temperature structure.
 * @param type: Type of sensor ie cpu, battery, gpu, skin etc.
 * @param sens_idx: Index for sensor of same type.
 *
 * @return 0 on success or negative value -errno on error.
 */
static int initialize_sensor(struct target_therm_cfg *v_sen_t,
                               struct vendor_temperature *sensor,
                               enum temperature_type type,
                               int sens_idx)
{
    if (v_sen_t == NULL || sensor == NULL ||
        sens_idx < 0) {
         ALOGE("%s:Invalid input, sens_idx%d\n", __func__, sens_idx);
         return -1;
    }

    sensor->tzn = get_tzn(v_sen_t->sensor_list[sens_idx]);
    if (sensor->tzn < 0) {
        ALOGE("No thermal zone for sensor: %s, ret:%d\n",
               v_sen_t->sensor_list[sens_idx], sensor->tzn);
        return -1;
    }
    if (type == DEVICE_TEMPERATURE_CPU)
        sensor->t.name = get_cpu_label(sens_idx);
    else
        sensor->t.name = v_sen_t->label;

    sensor->t.type = v_sen_t->type;
    sensor->mult = v_sen_t->mult;

    if (v_sen_t->throt_thresh != 0)
        sensor->t.throttling_threshold = v_sen_t->throt_thresh;
    else
        sensor->t.throttling_threshold = UNKNOWN_TEMPERATURE;

    if (v_sen_t->shutdwn_thresh != 0)
        sensor->t.shutdown_threshold = v_sen_t->shutdwn_thresh;
    else
        sensor->t.shutdown_threshold = UNKNOWN_TEMPERATURE;

    if (v_sen_t->vr_thresh != 0)
        sensor->t.vr_throttling_threshold = v_sen_t->vr_thresh;
    else
        sensor->t.vr_throttling_threshold = UNKNOWN_TEMPERATURE;

    return 0;
}

/**
 * Initialize all sensors.
 *
 * @param v_sen_t: Base pointer to array of target specific sensor configs.
 * @param cfg_cnt: Number of set of config for a given target.
 *
 * @return number of sensor on success or negative value or zero on error.
 */
int thermal_zone_init(struct target_therm_cfg *v_sen_t, int cfg_cnt)
{
    unsigned int idx = 0, cpu = 0;
    int j = 0;

    if (sensors != NULL && sensor_cnt != 0)
        return sensor_cnt;

    if (v_sen_t == NULL || cfg_cnt == 0) {
        ALOGE("%s:Invalid input\n", __func__);
        return -1;
    }
    sensors = calloc(get_num_cpus() + cfg_cnt - 1,
        sizeof(struct vendor_temperature));

    for (j = 0, idx = 0; j < cfg_cnt &&
                idx < (get_num_cpus() + cfg_cnt - 1); j++) {
        if (v_sen_t[j].type == DEVICE_TEMPERATURE_CPU) {
            /* Initialize cpu thermal zone id */
            for (cpu = 0; cpu < get_num_cpus() &&
                        idx < (get_num_cpus() + cfg_cnt - 1); cpu++, idx++) {
                if (initialize_sensor(&v_sen_t[j], &sensors[idx],
                      v_sen_t[j].type, cpu)) {
                        free(sensors);
                        return -1;
                }
           }
        } else {
            /* Initialize misc thermal zone id */
            if (initialize_sensor(&v_sen_t[j], &sensors[idx],
                  v_sen_t[j].type, 0)) {
                free(sensors);
                return -1;
            }
            idx++;
       }
    }
    sensor_cnt = idx;

    return sensor_cnt;
}

/**
 * Reads sensor temperature.
 *
 * @param sensor_num: thermal zone id for the sensor to be read
 * @param type: Device temperature type.
 * @param name: Device temperature name.
 * @param mult: Multiplier used to translate temperature to Celsius.
 * @param throttling_threshold: Throttling threshold for the sensor.
 * @param shutdown_threshold: Shutdown threshold for the sensor.
 * @param out: Pointer to temperature_t structure that will be filled with
 *     temperature values.
 *
 * @return 0 on success or negative value -errno on error.
 */
static ssize_t read_temperature(int sensor_num, int type, const char *name,
        float mult, float throttling_threshold, float shutdown_threshold,
        float vr_throttling_threshold,
        temperature_t *out) {
    ALOGD("Entering %s",__func__);
    char file_name[MAX_LENGTH];
    float temp;
    char buf[16] = {0};
    int ret = 0;

    snprintf(file_name, sizeof(file_name), TEMPERATURE_FILE_FORMAT, sensor_num);
    ret = read_line_from_file(file_name, buf, sizeof(buf));
    if (ret <= 0) {
        ALOGE("Temperature read error: %d for sensor[%d]:%s\n",
            ret, sensor_num, name);
	return -1;
    }
    temp = atof(buf);

    (*out) = (temperature_t) {
        .type = type,
        .name = name,
        .current_value = temp * mult,
        .throttling_threshold = throttling_threshold,
        .shutdown_threshold = shutdown_threshold,
        .vr_throttling_threshold = vr_throttling_threshold
    };

    return 0;
}

/**
 * Reads all sensor temperature.
 *
 * @param list: Base pointer to array of temperature_t structure that will be
 *     filled with temperature values.
 * @param size: Number of sensor temperature needs to be filled in list.
 *
 * @return number of sensor data filled on success or 0 or negative value
 *     -errno on error.
 */
ssize_t get_temperature_for_all(temperature_t *list, size_t size)
{
    ALOGD("Entering %s",__func__);
    size_t idx;

    if (sensors == NULL) {
        ALOGE("No sensor configured\n");
	return 0;
    }

    for (idx = 0; idx < sensor_cnt && idx < size; idx++) {
        ssize_t result = read_temperature(sensors[idx].tzn, sensors[idx].t.type,
                sensors[idx].t.name, sensors[idx].mult,
                sensors[idx].t.throttling_threshold,
                sensors[idx].t.shutdown_threshold,
                sensors[idx].t.vr_throttling_threshold,
                &list[idx]);
        if (result != 0)
            return result;
    }
    return idx;
}

