/******************************************************************************
 *
 *  Copyright (C) 2009-2012 Broadcom 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.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  Filename:      bte_conf.c
 *
 *  Description:   Contains functions to conduct run-time module configuration
 *                 based on entries present in the .conf file
 *
 ******************************************************************************/

#define LOG_TAG "bte_conf"

#include <assert.h>
#include <utils/Log.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#include "bt_target.h"
#include "bta_api.h"
#include "bt_utils.h"
#include "config.h"

/******************************************************************************
**  Externs
******************************************************************************/
extern BOOLEAN hci_logging_enabled;
extern char hci_logfile[256];
extern BOOLEAN trace_conf_enabled;
void bte_trace_conf(const char *p_name, const char *p_conf_value);
void bte_trace_conf_config(const config_t *config);
int device_name_cfg(const char *p_conf_name, const char *p_conf_value);
int device_class_cfg(const char *p_conf_name, const char *p_conf_value);
int logging_cfg_onoff(const char *p_conf_name, const char *p_conf_value);
int logging_set_filepath(const char *p_conf_name, const char *p_conf_value);
int trace_cfg_onoff(const char *p_conf_name, const char *p_conf_value);

BD_NAME local_device_default_name = BTM_DEF_LOCAL_NAME;
DEV_CLASS local_device_default_class = {0x40, 0x02, 0x0C};

/******************************************************************************
**  Local type definitions
******************************************************************************/
#define CONF_DBG          0
#define info(format, ...) ALOGI (format, ## __VA_ARGS__)
#define debug(format, ...) if (CONF_DBG) ALOGD (format, ## __VA_ARGS__)
#define error(format, ...) ALOGE (format, ## __VA_ARGS__)

#define CONF_KEY_LEN   32
#define CONF_VALUE_LEN 96

#define CONF_COMMENT '#'
#define CONF_DELIMITERS " =\n\r\t"
#define CONF_VALUES_DELIMITERS "\"=\n\r\t"
#define CONF_COD_DELIMITERS " {,}\t"
#define CONF_MAX_LINE_LEN 255

typedef int (conf_action_t)(const char *p_conf_name, const char *p_conf_value);

typedef struct {
    const char *key_name;
    conf_action_t *p_action;
} conf_entry_t;

typedef struct {
    char key[CONF_KEY_LEN];
    char value[CONF_VALUE_LEN];
} tKEY_VALUE_PAIRS;

enum {
    CONF_DID,
    CONF_DID_RECORD_NUM,
    CONF_DID_PRIMARY_RECORD,
    CONF_DID_VENDOR_ID,
    CONF_DID_VENDOR_ID_SOURCE,
    CONF_DID_PRODUCT_ID,
    CONF_DID_VERSION,
    CONF_DID_CLIENT_EXECUTABLE_URL,
    CONF_DID_SERVICE_DESCRIPTION,
    CONF_DID_DOCUMENTATION_URL,
    CONF_DID_MAX
};
typedef UINT8 tCONF_DID;
/******************************************************************************
**  Static variables
******************************************************************************/

/*
 * Current supported entries and corresponding action functions
 */
/* TODO: Name and Class are duplicated with NVRAM adapter_info. Need to be sorted out */
static const conf_entry_t conf_table[] = {
    /*{"Name", device_name_cfg},
    {"Class", device_class_cfg},*/
    {"BtSnoopLogOutput", logging_cfg_onoff},
    {"BtSnoopFileName", logging_set_filepath},
    {"TraceConf", trace_cfg_onoff},
    {(const char *) NULL, NULL}
};

static tKEY_VALUE_PAIRS did_conf_pairs[CONF_DID_MAX] = {
    { "[DID]",               "" },
    { "recordNumber",        "" },
    { "primaryRecord",       "" },
    { "vendorId",            "" },
    { "vendorIdSource",      "" },
    { "productId",           "" },
    { "version",             "" },
    { "clientExecutableURL", "" },
    { "serviceDescription",  "" },
    { "documentationURL",    "" },
};
/*****************************************************************************
**   FUNCTIONS
*****************************************************************************/

int device_name_cfg(const char *p_conf_name, const char *p_conf_value)
{
    UNUSED(p_conf_name);
    strcpy((char *)local_device_default_name, p_conf_value);
    return 0;
}

int device_class_cfg(const char *p_conf_name, const char *p_conf_value)
{
    char *p_token;
    unsigned int x;
    char tmp[1024] = { 0 };
    strncpy(tmp, p_conf_value, sizeof(tmp) - 1);

    UNUSED(p_conf_name);

    p_token = strtok(tmp, CONF_COD_DELIMITERS);
    sscanf(p_token, "%x", &x);
    local_device_default_class[0] = (UINT8) x;
    p_token = strtok(NULL, CONF_COD_DELIMITERS);
    sscanf(p_token, "%x", &x);
    local_device_default_class[1] = (UINT8) x;
    p_token = strtok(NULL, CONF_COD_DELIMITERS);
    sscanf(p_token, "%x", &x);
    local_device_default_class[2] = (UINT8) x;

    return 0;
}

int logging_cfg_onoff(const char *p_conf_name, const char *p_conf_value)
{
    UNUSED(p_conf_name);
    if (strcmp(p_conf_value, "true") == 0)
        hci_logging_enabled = TRUE;
    else
        hci_logging_enabled = FALSE;
    return 0;
}

int logging_set_filepath(const char *p_conf_name, const char *p_conf_value)
{
    UNUSED(p_conf_name);
    strcpy(hci_logfile, p_conf_value);
    return 0;
}

int trace_cfg_onoff(const char *p_conf_name, const char *p_conf_value)
{
    UNUSED(p_conf_name);
    trace_conf_enabled = (strcmp(p_conf_value, "true") == 0) ? TRUE : FALSE;
    return 0;
}

/*****************************************************************************
**   CONF INTERFACE FUNCTIONS
*****************************************************************************/

/*******************************************************************************
**
** Function        bte_load_conf
**
** Description     Read conf entry from path file one by one and call
**                 the corresponding config function
**
** Returns         None
**
*******************************************************************************/
void bte_load_conf(const char *path) {
  assert(path != NULL);

  ALOGI("%s attempt to load stack conf from %s", __func__, path);

  config_t *config = config_new(path);
  if (!config) {
    ALOGI("%s file >%s< not found", __func__, path);
    return;
  }

  for (const conf_entry_t *entry = &conf_table[0]; entry->key_name; ++entry) {
    const char *value = config_get_string(config, CONFIG_DEFAULT_SECTION, entry->key_name, NULL);
    if (value)
      entry->p_action(entry->key_name, value);
  }

  bte_trace_conf_config(config);
  config_free(config);
}

/*******************************************************************************
**
** Function        bte_parse_did_conf
**
** Description     Read conf entry from p_path file one by one and get
**                 the corresponding config value
**
** Returns         TRUE if success, else FALSE
**
*******************************************************************************/
static BOOLEAN bte_parse_did_conf (const char *p_path, UINT32 num,
    tKEY_VALUE_PAIRS *conf_pairs, UINT32 conf_pairs_num)
{
    UINT32 i, param_num=0, count=0, start_count=0, end_count=0, conf_num=0;
    BOOLEAN key=TRUE, conf_found=FALSE;

    FILE    *p_file;
    char    *p;
    char    line[CONF_MAX_LINE_LEN+1]; /* add 1 for \0 char */

    ALOGI("Attempt to load did conf from %s", p_path);

    if ((p_file = fopen(p_path, "r")) != NULL)
    {
        /* read line by line */
        while (fgets(line, CONF_MAX_LINE_LEN+1, p_file) != NULL)
        {
            count++;
            if (line[0] == CONF_COMMENT)
                continue;

            if (conf_found && (conf_num == num) && (*line == '[')) {
                conf_found = FALSE;
                end_count = count-1;
                break;
            }

            p = strtok(line, CONF_DELIMITERS);
            while (p != NULL) {
                if (conf_num <= num) {
                    if (key) {
                        if (!strcmp(p, conf_pairs[0].key)) {
                            if (++conf_num == num) {
                                conf_found = TRUE;
                                start_count = count;
                                strncpy(conf_pairs[0].value, "1", CONF_VALUE_LEN);
                            }
                        } else {
                            if (conf_num == num) {
                                for (i=1; i<conf_pairs_num; i++) {
                                    if (!strcmp(p, conf_pairs[i].key)) {
                                        param_num = i;
                                        break;
                                    }
                                }
                                if (i == conf_pairs_num) {
                                    error("Attribute %s does not belong to %s configuration",
                                        p, conf_pairs[0].key);
                                    fclose(p_file);
                                    return FALSE;
                                }
                            }
                            key = FALSE;
                        }
                    } else {
                        if ((conf_num == num) && param_num) {
                            strncpy(conf_pairs[param_num].value, p, CONF_VALUE_LEN-1);
                            param_num = 0;
                        }
                        key = TRUE;
                    }
                }
                p = strtok(NULL, CONF_DELIMITERS);
            }
        }

        fclose(p_file);
   }
   else
   {
        ALOGI( "bte_parse_did_conf file >%s< not found", p_path);
   }
   if (!end_count)
       end_count = count;

   if (start_count) {
        debug("Read %s configuration #%u from lines %u to %u in file %s",
            conf_pairs[0].key, (unsigned int)num, (unsigned int)start_count,
            (unsigned int)end_count, p_path);
        return TRUE;
   }

   error("%s configuration not found in file %s", conf_pairs[0].key, p_path);
        return FALSE;
}

/*******************************************************************************
**
** Function        bte_load_did_conf
**
** Description     Set local Device ID records, reading from configuration files
**
** Returns         None
**
*******************************************************************************/

void bte_load_did_conf (const char *p_path)
{
    tBTA_DI_RECORD rec;
    UINT32 rec_num, i, j;

    for (i=1; i<=BTA_DI_NUM_MAX; i++) {
        for (j=0; j<CONF_DID_MAX; j++) {
            *did_conf_pairs[j].value = 0;
        }

        if (bte_parse_did_conf(p_path, i, did_conf_pairs, CONF_DID_MAX)) {
            memset(&rec, 0, sizeof(rec));

            if (*did_conf_pairs[CONF_DID_RECORD_NUM].value) {
                rec_num = (UINT32)(strtoul(did_conf_pairs[CONF_DID_RECORD_NUM].value, NULL, 0)-1);
            } else {
                debug("[%d] Unknown %s", (unsigned int)i, did_conf_pairs[CONF_DID_RECORD_NUM].key);
                continue;
            }

            if (*did_conf_pairs[CONF_DID_VENDOR_ID].value) {
                rec.vendor = (UINT16)strtoul(did_conf_pairs[CONF_DID_VENDOR_ID].value, NULL, 0);
            } else {
                rec.vendor = LMP_COMPID_BROADCOM;
            }

            if (*did_conf_pairs[CONF_DID_VENDOR_ID_SOURCE].value) {
                rec.vendor_id_source = (UINT16)strtoul(did_conf_pairs[CONF_DID_VENDOR_ID_SOURCE].value, NULL, 0);
            } else {
                rec.vendor_id_source = DI_VENDOR_ID_SOURCE_BTSIG;
            }

            if ((*did_conf_pairs[CONF_DID].value == 0) ||
                (rec_num >= BTA_DI_NUM_MAX) ||
                (!((rec.vendor_id_source >= DI_VENDOR_ID_SOURCE_BTSIG) &&
                   (rec.vendor_id_source <= DI_VENDOR_ID_SOURCE_USBIF))) ||
                (rec.vendor == DI_VENDOR_ID_DEFAULT)) {

                error("DID record #%u not set", (unsigned int)i);
                for (j=0; j<CONF_DID_MAX; j++) {
                    error("%s:%s", did_conf_pairs[j].key, did_conf_pairs[j].value);
                }
                continue;
            }

            rec.product = (UINT16)strtoul(did_conf_pairs[CONF_DID_PRODUCT_ID].value, NULL, 0);
            rec.version = (UINT16)strtoul(did_conf_pairs[CONF_DID_VERSION].value, NULL, 0);

            strncpy(rec.client_executable_url,
                did_conf_pairs[CONF_DID_CLIENT_EXECUTABLE_URL].value,
                SDP_MAX_ATTR_LEN);
            strncpy(rec.service_description,
                did_conf_pairs[CONF_DID_SERVICE_DESCRIPTION].value,
                SDP_MAX_ATTR_LEN);
            strncpy(rec.documentation_url,
                did_conf_pairs[CONF_DID_DOCUMENTATION_URL].value,
                SDP_MAX_ATTR_LEN);

            for (j=0; j<strlen(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value); j++) {
                did_conf_pairs[CONF_DID_PRIMARY_RECORD].value[j] =
                    tolower(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value[j]);
            }
            if ((!strcmp(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value, "true")) ||
                (!strcmp(did_conf_pairs[CONF_DID_PRIMARY_RECORD].value, "1"))) {
                rec.primary_record = TRUE;
            } else {
                rec.primary_record = FALSE;
            }

            info("[%u] primary_record=%d vendor_id=0x%04X vendor_id_source=0x%04X product_id=0x%04X version=0x%04X",
                (unsigned int)rec_num+1, rec.primary_record, rec.vendor,
                rec.vendor_id_source, rec.product, rec.version);
            if (*rec.client_executable_url) {
                info(" client_executable_url=%s", rec.client_executable_url);
            }
            if (*rec.service_description) {
                info(" service_description=%s", rec.service_description);
            }
            if (*rec.documentation_url) {
                info(" documentation_url=%s", rec.documentation_url);
            }

            if (BTA_DmSetLocalDiRecord(&rec, &rec_num) != BTA_SUCCESS) {
                error("SetLocalDiInfo failed for #%u!", (unsigned int)i);
            }
        }
    }
}
