/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <log_util.h>
#include "loc_target.h"
#include "loc_log.h"
#include <loc_pla.h>

#define APQ8064_ID_1 "109"
#define APQ8064_ID_2 "153"
#define MPQ8064_ID_1 "130"
#define MSM8930_ID_1 "142"
#define MSM8930_ID_2 "116"
#define APQ8030_ID_1 "157"
#define APQ8074_ID_1 "184"

#define LINE_LEN 100
#define STR_LIQUID      "Liquid"
#define STR_SURF        "Surf"
#define STR_MTP         "MTP"
#define STR_APQ         "apq"
#define STR_SDC         "sdc"  // alternative string for APQ targets
#define STR_MSM         "msm"
#define STR_SDM         "sdm"  // alternative string for MSM targets
#define STR_APQ_NO_WGR  "baseband_apq_nowgr"
#define STR_AUTO        "auto"
#define IS_STR_END(c) ((c) == '\0' || (c) == '\n' || (c) == '\r')
#define LENGTH(s) (sizeof(s) - 1)
#define GPS_CHECK_NO_ERROR 0
#define GPS_CHECK_NO_GPS_HW 1

static unsigned int gTarget = (unsigned int)-1;

static int read_a_line(const char * file_path, char * line, int line_size)
{
    FILE *fp;
    int result = 0;

    * line = '\0';
    fp = fopen(file_path, "r" );
    if( fp == NULL ) {
        LOC_LOGE("open failed: %s: %s\n", file_path, strerror(errno));
        result = -1;
    } else {
        int len;
        fgets(line, line_size, fp);
        len = strlen(line);
        len = len < line_size - 1? len : line_size - 1;
        line[len] = '\0';
        LOC_LOGD("cat %s: %s", file_path, line);
        fclose(fp);
    }
    return result;
}

/*The character array passed to this function should have length
  of atleast PROPERTY_VALUE_MAX*/
void loc_get_target_baseband(char *baseband, int array_length)
{
    if(baseband && (array_length >= PROPERTY_VALUE_MAX)) {
        property_get("ro.baseband", baseband, "");
        LOC_LOGD("%s:%d]: Baseband: %s\n", __func__, __LINE__, baseband);
    }
    else {
        LOC_LOGE("%s:%d]: NULL parameter or array length less than PROPERTY_VALUE_MAX\n",
                 __func__, __LINE__);
    }
}

/*The character array passed to this function should have length
  of atleast PROPERTY_VALUE_MAX*/
void loc_get_platform_name(char *platform_name, int array_length)
{
    if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) {
        property_get("ro.board.platform", platform_name, "");
        LOC_LOGD("%s:%d]: Target name: %s\n", __func__, __LINE__, platform_name);
    }
    else {
        LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n",
                 __func__, __LINE__);
    }
}

/*The character array passed to this function should have length
  of atleast PROPERTY_VALUE_MAX*/
void loc_get_auto_platform_name(char *platform_name, int array_length)
{
    if(platform_name && (array_length >= PROPERTY_VALUE_MAX)) {
        property_get("ro.hardware.type", platform_name, "");
        LOC_LOGD("%s:%d]: Autoplatform name: %s\n", __func__, __LINE__, platform_name);
    }
    else {
        LOC_LOGE("%s:%d]: Null parameter or array length less than PROPERTY_VALUE_MAX\n",
                 __func__, __LINE__);
    }
}

unsigned int loc_get_target(void)
{
    if (gTarget != (unsigned int)-1)
        return gTarget;

    static const char hw_platform[]      = "/sys/devices/soc0/hw_platform";
    static const char id[]               = "/sys/devices/soc0/soc_id";
    static const char hw_platform_dep[]  =
        "/sys/devices/system/soc/soc0/hw_platform";
    static const char id_dep[]           = "/sys/devices/system/soc/soc0/id";
    static const char mdm[]              = "/target"; // mdm target we are using

    char rd_hw_platform[LINE_LEN];
    char rd_id[LINE_LEN];
    char rd_mdm[LINE_LEN];
    char baseband[LINE_LEN];
    char rd_auto_platform[LINE_LEN];

    loc_get_target_baseband(baseband, sizeof(baseband));

    if (!access(hw_platform, F_OK)) {
        read_a_line(hw_platform, rd_hw_platform, LINE_LEN);
    } else {
        read_a_line(hw_platform_dep, rd_hw_platform, LINE_LEN);
    }
    if (!access(id, F_OK)) {
        read_a_line(id, rd_id, LINE_LEN);
    } else {
        read_a_line(id_dep, rd_id, LINE_LEN);
    }

    /*check automotive platform*/
    loc_get_auto_platform_name(rd_auto_platform, sizeof(rd_auto_platform));
    if( !memcmp(rd_auto_platform, STR_AUTO, LENGTH(STR_AUTO)) )
    {
          gTarget = TARGET_AUTO;
          goto detected;
    }

    if( !memcmp(baseband, STR_APQ_NO_WGR, LENGTH(STR_APQ_NO_WGR)) ){

        gTarget = TARGET_NO_GNSS;
        goto detected;
    }

    if( !memcmp(baseband, STR_APQ, LENGTH(STR_APQ)) ||
        !memcmp(baseband, STR_SDC, LENGTH(STR_SDC)) ) {

        if( !memcmp(rd_id, MPQ8064_ID_1, LENGTH(MPQ8064_ID_1))
            && IS_STR_END(rd_id[LENGTH(MPQ8064_ID_1)]) )
            gTarget = TARGET_NO_GNSS;
        else
            gTarget = TARGET_APQ_SA;
    } else if (((!memcmp(rd_hw_platform, STR_LIQUID, LENGTH(STR_LIQUID))
                 && IS_STR_END(rd_hw_platform[LENGTH(STR_LIQUID)])) ||
                (!memcmp(rd_hw_platform, STR_SURF,   LENGTH(STR_SURF))
                 && IS_STR_END(rd_hw_platform[LENGTH(STR_SURF)])) ||
                (!memcmp(rd_hw_platform, STR_MTP,   LENGTH(STR_MTP))
                 && IS_STR_END(rd_hw_platform[LENGTH(STR_MTP)]))) &&
               !read_a_line( mdm, rd_mdm, LINE_LEN)) {
        gTarget = TARGET_MDM;
    } else if( (!memcmp(rd_id, MSM8930_ID_1, LENGTH(MSM8930_ID_1))
                && IS_STR_END(rd_id[LENGTH(MSM8930_ID_1)])) ||
               (!memcmp(rd_id, MSM8930_ID_2, LENGTH(MSM8930_ID_2))
                && IS_STR_END(rd_id[LENGTH(MSM8930_ID_2)])) ) {
        gTarget = TARGET_MSM_NO_SSC;
    } else if ( !memcmp(baseband, STR_MSM, LENGTH(STR_MSM)) ||
                !memcmp(baseband, STR_SDM, LENGTH(STR_SDM)) ) {
        gTarget = TARGET_DEFAULT;
    } else {
        gTarget = TARGET_UNKNOWN;
    }

detected:
    LOC_LOGW("HAL: %s returned %d", __FUNCTION__, gTarget);
    return gTarget;
}

/*Reads the property ro.lean to identify if this is a lean target
  Returns:
  0 if not a lean and mean target
  1 if this is a lean and mean target
*/
int loc_identify_lean_target()
{
    char lean_target[PROPERTY_VALUE_MAX];
    property_get("ro.lean", lean_target, "");
    LOC_LOGD("%s:%d]: lean target: %s\n", __func__, __LINE__, lean_target);
    return !(strncmp(lean_target, "true", PROPERTY_VALUE_MAX));
}
