/*
 * Copyright (c) 2017, 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 <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#define LOG_TAG "ThermalHAL-845"
#include <log/log.h>

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

#define MAX_LENGTH                    50

#define TEMPERATURE_FILE_FORMAT       "/sys/class/thermal/thermal_zone%d/temp"

#define BATTERY_SENSOR_NUM            60
#define GPU_SENSOR_NUM                11
#define SKIN_SENSOR_NUM               56

const int CPU_SENSORS[] = {1, 2, 3, 4, 7, 8, 9,10};

#define CPU_NUM                       (sizeof(CPU_SENSORS) / sizeof(int))
// Sum of CPU_NUM + 3 for GPU, BATTERY, and SKIN.
#define TEMPERATURE_NUM               (CPU_NUM + 3)

//therm-reset-temp
#define CPU_SHUTDOWN_THRESHOLD        115
//limit-temp
#define CPU_THROTTLING_THRESHOLD      60
#define BATTERY_SHUTDOWN_THRESHOLD    60
//must match thermal-engine.conf
#define SKIN_THROTTLING_THRESHOLD     44
#define SKIN_SHUTDOWN_THRESHOLD       70
#define VR_THROTTLED_BELOW_MIN        58

#define GPU_LABEL                     "GPU"
#define BATTERY_LABEL                 "battery"
#define SKIN_LABEL                    "skin"

const char *CPU_LABEL[] = {"CPU0", "CPU1", "CPU2", "CPU3", "CPU4", "CPU5", "CPU6", "CPU7"};

const char *get_cpu_label(unsigned int cpu_num) {
    ALOGD("Entering %s",__func__);
    if(cpu_num >= CPU_NUM)
        return NULL;

    return CPU_LABEL[cpu_num];
}

size_t get_num_cpus() {
    ALOGD("Entering %s",__func__);
    return CPU_NUM;
}

/**
 * Reads device temperature.
 *
 * @param sensor_num Number of sensor file with temperature.
 * @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 temperature.
 * @param shutdown_threshold Shutdown threshold for the temperature.
 * @param out Pointer to temperature_t structure that will be filled with current
 *     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__);
    FILE *file;
    char file_name[MAX_LENGTH];
    float temp;

    snprintf(file_name, sizeof(file_name), TEMPERATURE_FILE_FORMAT, sensor_num);
    file = fopen(file_name, "r");
    if (file == NULL) {
        ALOGE("%s: failed to open: %s", __func__, strerror(errno));
        return -errno;
    }
    if (1 != fscanf(file, "%f", &temp)) {
        fclose(file);
        ALOGE("%s: failed to read a float: %s", __func__, strerror(errno));
        return errno ? -errno : -EIO;
    }

    fclose(file);

    (*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;
}

static ssize_t get_cpu_temperatures(temperature_t *list, size_t size) {
    ALOGD("Entering %s",__func__);
    size_t cpu;
    for (cpu = 0; cpu < CPU_NUM; cpu++) {
        if (cpu >= size) {
            break;
        }
        // tsens_tz_sensor[4,6,9,11]: temperature in decidegrees Celsius.
        ssize_t result = read_temperature(CPU_SENSORS[cpu], DEVICE_TEMPERATURE_CPU, CPU_LABEL[cpu],
                0.001, CPU_THROTTLING_THRESHOLD, CPU_SHUTDOWN_THRESHOLD, UNKNOWN_TEMPERATURE,
                &list[cpu]);
        if (result != 0) {
            return result;
        }
    }

    return cpu;
}

ssize_t get_temperatures(thermal_module_t *module, temperature_t *list, size_t size) {
    ALOGD("Entering %s",__func__);
    ssize_t result = 0;
    size_t current_index = 0;

    if (list == NULL) {
        return TEMPERATURE_NUM;
    }

    result = get_cpu_temperatures(list, size);
    if (result < 0) {
        return result;
    }
    current_index += result;

    // GPU temperature.
    if (current_index < size) {
        // tsens_tz_sensor14: temperature in millidegrees Celsius.
        result = read_temperature(GPU_SENSOR_NUM, DEVICE_TEMPERATURE_GPU, GPU_LABEL, 0.001,
                UNKNOWN_TEMPERATURE, UNKNOWN_TEMPERATURE, UNKNOWN_TEMPERATURE,
                &list[current_index]);
        if (result < 0) {
            return result;
        }
        current_index++;
    }

    // Battery temperature.
    if (current_index < size) {
        // tsens_tz_sensor29: battery: temperature in millidegrees Celsius.
        result = read_temperature(BATTERY_SENSOR_NUM, DEVICE_TEMPERATURE_BATTERY, BATTERY_LABEL,
                0.001, UNKNOWN_TEMPERATURE, BATTERY_SHUTDOWN_THRESHOLD, UNKNOWN_TEMPERATURE,
                &list[current_index]);
        if (result < 0) {
            return result;
        }
        current_index++;
    }

    // Skin temperature.
    if (current_index < size) {
        // tsens_tz_sensor24: temperature in millidegrees Celsius.
        result = read_temperature(SKIN_SENSOR_NUM, DEVICE_TEMPERATURE_SKIN, SKIN_LABEL, .001,
                SKIN_THROTTLING_THRESHOLD, SKIN_SHUTDOWN_THRESHOLD, VR_THROTTLED_BELOW_MIN,
                &list[current_index]);
        if (result < 0) {
            return result;
        }
        current_index++;
    }
    return TEMPERATURE_NUM;
}
