/*
 * 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.
 */

#define LOG_TAG "VrHALImpl"

#include <cutils/log.h>

#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

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

#include <thermal_client.h>
#include "vr_int.h"


static void *dlhandle;
static int (*p_thermal_client_config_query)(char *, struct config_instance **);
static int (*p_thermal_client_config_set)(struct config_instance *, unsigned int);
static void (*p_thermal_client_config_cleanup)(struct config_instance *, unsigned int);

static int max_string_size = 36;
static int error_state = 0; //global error state - don't do anything if set!

#define DEBUG 0

static thermal_cfg_info_t non_vr_thermal_cfgs;
static thermal_cfg_info_t vr_thermal_cfgs;

int __attribute__ ((weak)) load_thermal_cfg_info(thermal_cfg_info_t *non_vr,
                                                 thermal_cfg_info_t *vr) {
    ALOGD("Entering %s",__func__);
    non_vr->num_cfgs = 0;
    vr->num_cfgs = 0;

    return 0;
}

/**
 * Debug function for printing out a log instance
 */
static void log_config_instance(struct config_instance *instance ){
    ALOGI("logging config_instance 0x%p", instance);
    ALOGI("config_instance: cfg_desc = %s", instance->cfg_desc);
    ALOGI("config_instance: algo_type = %s", instance->algo_type);
    ALOGI("config_instance: fields_mask = 0x%x", instance->fields_mask);
    ALOGI("config_instance: num_fields = %u", instance->num_fields);
    for (uint32_t i = 0; i < instance->num_fields; i++) {
        ALOGI("config_instance: field_data[%d]", i);
        ALOGI("\tfield_name = %s", instance->fields[i].field_name);
        ALOGI("\tdata_type = %u", instance->fields[i].data_type);
        ALOGI("\tnum_data = %u", instance->fields[i].num_data);
        switch (instance->fields[i].data_type){
            case FIELD_INT: ALOGI("\tdata = %d", *(int*)(instance->fields[i].data));
                break;
            case FIELD_STR: ALOGI("\tdata = %s", (char*)(instance->fields[i].data));
                break;
            default: ALOGI("\tdata = 0x%p", instance->fields[i].data);
                break;
        }
    }
}

/**
 * Debug function for printing out all instances of "ss" and "monitor" algos
 */
static void query_thermal_config(){
    ALOGD("Entering %s",__func__);
    struct config_instance *instances;

    int num_configs = (*p_thermal_client_config_query)("ss", &instances);
    if (num_configs <= 0) {
        return;
    }
    for (int i = 0; i < num_configs; i++) {
        log_config_instance(&(instances[i]));
    }
    if (num_configs > 0) {
        (*p_thermal_client_config_cleanup)(instances, num_configs);
    }

    num_configs = (*p_thermal_client_config_query)("monitor", &instances);
    if (num_configs <= 0) {
        return;
    }
    for (int i = 0; i < num_configs; i++) {
        log_config_instance(&(instances[i]));
    }
    if (num_configs > 0) {
        (*p_thermal_client_config_cleanup)(instances, num_configs);
    }
}

/**
 * Load the thermal client library
 * returns 0 on success
 */
static int load_thermal_client(void){
    ALOGD("Entering %s",__func__);
    char *thermal_client_so = "vendor/lib64/libthermalclient.so";

    dlhandle = dlopen(thermal_client_so, RTLD_NOW | RTLD_LOCAL);
    if (dlhandle) {
        dlerror();
        p_thermal_client_config_query = (int (*) (char *, struct config_instance **))
            dlsym(dlhandle, "thermal_client_config_query");
        if (dlerror()) {
            ALOGE("Unable to load thermal_client_config_query");
            goto error_handle;
        }

        p_thermal_client_config_set = (int (*) (struct config_instance *, unsigned int))
            dlsym(dlhandle, "thermal_client_config_set");
        if (dlerror()) {
            ALOGE("Unable to load thermal_client_config_set");
            goto error_handle;
        }

        p_thermal_client_config_cleanup = (void (*) (struct config_instance *, unsigned int))
            dlsym(dlhandle, "thermal_client_config_cleanup");
        if (dlerror()) {
            ALOGE("Unable to load thermal_client_config_cleanup");
            goto error_handle;
        }
    } else {
        ALOGE("unable to open %s", thermal_client_so);
        return -1;
    }
	return 0;

error_handle:
    ALOGE("Error opening functions from %s", thermal_client_so);
    p_thermal_client_config_query = NULL;
    p_thermal_client_config_set = NULL;
    p_thermal_client_config_cleanup = NULL;
    dlclose(dlhandle);
    dlhandle = NULL;
    return -1;
}

/**
 *  Free the config_instance as allocated in allocate_config_instance
 */
static void free_config_instance(struct config_instance *config){

    if (config) {
        if (config->fields) {
            free(config->fields[0].data);
            free(config->fields[0].field_name);
            free(config->fields);
        }
        free(config->algo_type);
        free(config->cfg_desc);
        free(config);
    }
}

/**
 *  Allocate a new struct config_instance for modifying the disable field
 */
static struct config_instance *allocate_config_instance(){
    ALOGD("Entering %s",__func__);
    struct config_instance *config = (struct config_instance *)malloc(sizeof(struct config_instance));
    if (!config) {
        ALOGE("Unable to allocate memory for config");
        return NULL;
    }
    memset(config, 0, sizeof(*config));

    config->cfg_desc = (char *)malloc(sizeof(char) * max_string_size);
    if (!config->cfg_desc) {
        free_config_instance(config);
        ALOGE("Unable to allocate memory for config->cfg_desc");
        return NULL;
    }
    memset(config->cfg_desc, 0, sizeof(char)*max_string_size);

    config->algo_type = (char *)malloc(sizeof(char) * max_string_size);
    if (!config->algo_type) {
        free_config_instance(config);
        ALOGE("Unable to allocate memory for config->algo_type");
        return NULL;
    }
    memset(config->algo_type, 0, sizeof(char) * max_string_size);

    config->fields = (struct field_data *)malloc(sizeof(struct field_data));
    if (!config->fields) {
        free_config_instance(config);
        ALOGE("Unable to allocate memory for config->fields");
        return NULL;
    }
    memset(config->fields, 0, sizeof(*config->fields));

    config->fields[0].field_name = (char*)malloc(sizeof(char) * max_string_size);
    if (!config->fields[0].field_name) {
        free_config_instance(config);
        ALOGE("Unable to allocate memory for config->fields[0].field_name");
        return NULL;
    }
    memset(config->fields[0].field_name, 0, sizeof(char) * max_string_size);

    config->fields[0].data = (void*)malloc(sizeof(int));
    if (!config->fields[0].data) {
        free_config_instance(config);
        ALOGE("Unable to allocate memory for config->fields[0].data");
        return NULL;
    }

    return config;
}

/**
 *  disable a thermal config
 *  returns 1 on success, anything else is a failure
 */
static int disable_config(char *config_name, char *algo_type){
    ALOGD("Entering %s",__func__);
    int result = 0;
    if (error_state) {
        return 0;
    }
    struct config_instance *config = allocate_config_instance();
    if (!config) {
        return 0;
    }
    strlcpy(config->cfg_desc, config_name, max_string_size);
    strlcpy(config->algo_type, algo_type, max_string_size);
    strlcpy(config->fields[0].field_name, "disable", max_string_size);

    config->fields_mask |= DISABLE_FIELD;
    config->num_fields = 1;
    config->fields[0].data_type = FIELD_INT;
    config->fields[0].num_data = 1;
    *(int*)(config->fields[0].data) = 1; //DISABLE


    result = (*p_thermal_client_config_set)(config, 1);
    if (DEBUG) {
        ALOGE("disable profile: name = %s, algo_type = %s, success = %d", config_name, algo_type, result);
    }
    free_config_instance(config);

    return result;
}

/**
 *  enable a thermal config
 *  returns 1 on success, anything else is failure
 */
static int enable_config(char *config_name, char *algo_type){
    ALOGD("Entering %s",__func__);
    int result = 0;
    if (error_state) {
        return 0;
    }
    struct config_instance *config = allocate_config_instance();
    if (!config) {
        return 0;
    }
    strlcpy(config->cfg_desc, config_name, max_string_size);
    strlcpy(config->algo_type, algo_type, max_string_size);
    strlcpy(config->fields[0].field_name, "disable", max_string_size);

    config->fields_mask |= DISABLE_FIELD;
    config->num_fields = 1;
    config->fields[0].data_type = FIELD_INT;
    config->fields[0].num_data = 1;
    *(int*)(config->fields[0].data) = 0;  //ENABLE

    result = (*p_thermal_client_config_set)(config, 1);
    if (DEBUG) {
        ALOGE("enable profile: name = %s, algo_type = %s, success = %d",
          config_name, algo_type, result);
    }

    free_config_instance(config);

    return result;
}

/**
 * Call this if there is a compoenent-fatal error
 * Attempts to clean up any outstanding thermal config state
 */
static void error_cleanup(){
    ALOGD("Entering %s",__func__);
    //disable VR configs, best-effort so ignore return values
    for (unsigned int i = 0; i < vr_thermal_cfgs.num_cfgs; i++) {
        disable_config(vr_thermal_cfgs.cfgs[i].config_name, vr_thermal_cfgs.cfgs[i].algo_name);
    }

    // enable non-VR profile, best-effort so ignore return values
    for (unsigned int i = 0; i < non_vr_thermal_cfgs.num_cfgs; i++) {
        enable_config(non_vr_thermal_cfgs.cfgs[i].config_name, non_vr_thermal_cfgs.cfgs[i].algo_name);
    }

    // set global error flag
    error_state = 1;
}

/*
 * Set global display/GPU/scheduler configuration to used for VR apps.
 */
static void set_vr_thermal_configuration() {
    ALOGD("Entering %s",__func__);
    int result = 1;
    if (error_state) {
        return;
    }
    //disable non-VR configs
    for (unsigned int i = 0; i < non_vr_thermal_cfgs.num_cfgs; i++) {
          result = disable_config(non_vr_thermal_cfgs.cfgs[i].config_name, non_vr_thermal_cfgs.cfgs[i].algo_name);
          if (result != 1)
          {
             goto error;
          }
    }

    //enable VR configs
    for (unsigned int i = 0; i < vr_thermal_cfgs.num_cfgs; i++) {
        result = enable_config(vr_thermal_cfgs.cfgs[i].config_name, vr_thermal_cfgs.cfgs[i].algo_name);
        if (result != 1)
        {
            goto error;
        }
    }

    if (DEBUG) {
        query_thermal_config();
    }

    return;

error:
    error_cleanup();
    return;
}

/*
 * Reset to default global display/GPU/scheduler configuration.
 */
static void unset_vr_thermal_configuration() {
    ALOGD("Entering %s",__func__);
    int result = 1;
    if (error_state) {
        return;
    }

    //disable VR configs
    for (unsigned int i = 0; i < vr_thermal_cfgs.num_cfgs; i++) {
        result = disable_config(vr_thermal_cfgs.cfgs[i].config_name, vr_thermal_cfgs.cfgs[i].algo_name);
        if (result != 1) {
            goto error;
        }
    }

    // enable non-VR profile
    for (unsigned int i = 0; i < non_vr_thermal_cfgs.num_cfgs; i++) {
        result = enable_config(non_vr_thermal_cfgs.cfgs[i].config_name, non_vr_thermal_cfgs.cfgs[i].algo_name);
        if (result != 1) {
            goto error;
        }
    }

    if (DEBUG) {
        query_thermal_config();
    }

    return;

error:
    error_cleanup();
    return;
}

static void vr_init(struct vr_module *module){
    ALOGD("Entering %s",__func__);
    int success = load_thermal_client();
    if (success != 0) {
        ALOGE("failed to load thermal client");
        error_state = 1;
    }
    success = load_thermal_cfg_info(&non_vr_thermal_cfgs, &vr_thermal_cfgs);
    if (success != 0) {
        ALOGE("failed to load thermal configs");
        error_state = 1;
    }

}

static void vr_set_vr_mode(struct vr_module *module, bool enabled){
    ALOGD("Entering %s",__func__);
    if (enabled) {
        set_vr_thermal_configuration();
    } else {
        unset_vr_thermal_configuration();
    }
}

static struct hw_module_methods_t vr_module_methods = {
    .open = NULL, // There are no devices for this HAL interface.
};


vr_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = VR_MODULE_API_VERSION_1_0,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = VR_HARDWARE_MODULE_ID,
        .name               = "VR HAL",
        .author             = "Code Aurora Forum",
        .methods            = &vr_module_methods,
    },

    .init = vr_init,
    .set_vr_mode = vr_set_vr_mode,
};
