#include <string.h>
#include <stdint.h>
#include <cutils/properties.h>
#include <unistd.h>

#include "mbtk_type.h"
#include "mbtk_utils.h"

#include "mbtk_device.h"

/*
* Exec shell command.
*/
static bool shell_cmd_exec(const char *cmd, char *buf, int buf_size){
    FILE *fcmd;
    bool result = FALSE;
    fcmd = popen(cmd, "r");
    memset(buf, 0, buf_size);
    if(fcmd)
    {
        int pos = 0;
        int len = 0;

        while(!ferror(fcmd) && !feof(fcmd))
        {
            if(buf_size - pos == 0)
            {
                break;
            }
            len = fread(buf + pos,1,buf_size - pos,fcmd);
            if(len > 0)
                pos += len;
        }

        if(buf_size == pos)
            buf[buf_size - 1] = '\0';

        pclose(fcmd);
        result = TRUE;
    }

//    LOGV("%s [result:%d]: %s",cmd,result,buf);

    return result;
}


static char* band_2_str(mbtk_modem_band_area_enum band_area)
{
    switch(band_area)
    {
        case MBTK_MODEM_BAND_AREA_CN:
            return "CN";
        case MBTK_MODEM_BAND_AREA_EU:
            return "EU";
        case MBTK_MODEM_BAND_AREA_SA:
            return "SA";
        default:
            return "ALL";
    }
}

static char* net_support_str_get(uint32 net_support)
{
    static char net_str[100] = {0};

    if(net_support & MBTK_NET_SUPPORT_2G) { // GSM
        if(strlen(net_str) > 0) {
            strcat(net_str, "/2G");
        } else {
            strcat(net_str, "2G");
        }
    }

    if(net_support & MBTK_NET_SUPPORT_3G) { // WCDMA
        if(strlen(net_str) > 0) {
            strcat(net_str, "/3G");
        } else {
            strcat(net_str, "3G");
        }
    }

    if(net_support & MBTK_NET_SUPPORT_4G) { // LTE
        if(strlen(net_str) > 0) {
            strcat(net_str, "/4G");
        } else {
            strcat(net_str, "4G");
        }
    }

    if(net_support & MBTK_NET_SUPPORT_5G) { // NR
        if(strlen(net_str) > 0) {
            strcat(net_str, "/5G");
        } else {
            strcat(net_str, "5G");
        }
    }
    return net_str;
}

static char* band_str_get(uint32 band, int index)
{
    int band_list[33] = {0};
    int ret = mbtk_band_2_list(band, index, band_list);
    if(ret > 0) {
        static char buff[150] = {0};
        memset(buff, 0, sizeof(buff));
        int i = 0;
        while(i < ret) {
            if(strlen(buff) > 0) {
                sprintf(buff + strlen(buff), "/b%d", band_list[i]);
            } else {
                sprintf(buff + strlen(buff), "b%d", band_list[i]);
            }
            i++;
        }
        return buff;
    } else {
        return "NON";
    }
}

static void band_support_init(mbtk_device_info_modem_t *info_modem)
{
    memset(info_modem, 0, sizeof(mbtk_device_info_modem_t));
    if(mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_MODEM, info_modem, sizeof(mbtk_device_info_modem_t))) {
        printf("mbtk_dev_info_read(MODEM) fail, use default band.\n");
        info_modem->version = DEV_INFO_VERSION_V2;
        info_modem->modem.v2.band_area = MBTK_MODEM_BAND_AREA_ALL;
#ifdef MBTK_5G_SUPPORT
        info_modem->modem.v2.net_pref = 19; // MBTK_NET_PREF_LTE_NR_NR_PREF
        info_modem->modem.v2.net_support = MBTK_NET_SUPPORT_4G | MBTK_NET_SUPPORT_5G;

        info_modem->modem.v2.band_gsm = 0;
        info_modem->modem.v2.band_wcdma = 0;
        info_modem->modem.v2.band_tdlte = MBTK_BAND_ALL_TDLTE_DEFAULT;
        info_modem->modem.v2.band_fddlte = MBTK_BAND_ALL_FDDLTE_DEFAULT;
        info_modem->modem.v2.band_lte_ext = MBTK_BAND_ALL_EXT_LTE_DEFAULT;

        info_modem->modem.v2.band_nr_3 = MBTK_BAND_ALL_NR_3_DEFAULT;
        info_modem->modem.v2.band_nr_2 = MBTK_BAND_ALL_NR_2_DEFAULT;
        info_modem->modem.v2.band_nr_1 = MBTK_BAND_ALL_NR_1_DEFAULT;
        info_modem->modem.v2.band_nr_0 = MBTK_BAND_ALL_NR_0_DEFAULT;
#else
        info_modem->modem.v2.net_pref = 15; // MBTK_NET_PREF_GSM_UMTS_LTE_LTE_PREF
        info_modem->modem.v2.net_support = MBTK_NET_SUPPORT_2G | MBTK_NET_SUPPORT_3G | MBTK_NET_SUPPORT_4G;

        info_modem->modem.v2.band_gsm = MBTK_BAND_ALL_GSM_DEFAULT;
        info_modem->modem.v2.band_wcdma = MBTK_BAND_ALL_WCDMA_DEFAULT;
        info_modem->modem.v2.band_tdlte = MBTK_BAND_ALL_TDLTE_DEFAULT;
        info_modem->modem.v2.band_fddlte = MBTK_BAND_ALL_FDDLTE_DEFAULT;
        info_modem->modem.v2.band_lte_ext = MBTK_BAND_ALL_EXT_LTE_DEFAULT;

        info_modem->modem.v2.band_nr_3 = 0;
        info_modem->modem.v2.band_nr_2 = 0;
        info_modem->modem.v2.band_nr_1 = 0;
        info_modem->modem.v2.band_nr_0 = 0;
#endif
    }
}

static int band_set_by_at(mbtk_device_info_modem_t *band)
{
    char cmd[100] = {0};
    char rsp[100] = {0};

    // Only support 4G/5G
    if(band->modem.v2.net_support & MBTK_NET_SUPPORT_5G) {
        // AT*band=19,0,0,482,134742231,0,24576,256,134217877,0
        if(band->modem.v2.band_lte_ext > 0) {
            sprintf(cmd, "serial_atcmd AT*BAND=%d,%d,%d,%d,%d,%d,%d,%d,%d,0,,,,%d", band->modem.v2.net_pref, band->modem.v2.band_gsm,
                band->modem.v2.band_wcdma, band->modem.v2.band_tdlte, band->modem.v2.band_fddlte,
                band->modem.v2.band_nr_3, band->modem.v2.band_nr_2, band->modem.v2.band_nr_1,
                band->modem.v2.band_nr_0, band->modem.v2.band_lte_ext);
        } else {
            sprintf(cmd, "serial_atcmd AT*BAND=%d,%d,%d,%d,%d,%d,%d,%d,%d,0", band->modem.v2.net_pref, band->modem.v2.band_gsm,
                band->modem.v2.band_wcdma, band->modem.v2.band_tdlte, band->modem.v2.band_fddlte,
                band->modem.v2.band_nr_3, band->modem.v2.band_nr_2, band->modem.v2.band_nr_1, band->modem.v2.band_nr_0);
        }
    } else {
        if(band->modem.v2.band_lte_ext > 0) {
            sprintf(cmd, "serial_atcmd AT*BAND=%d,%d,%d,%d,%d,,,,%d", band->modem.v2.net_pref, band->modem.v2.band_gsm, band->modem.v2.band_wcdma,
                band->modem.v2.band_tdlte, band->modem.v2.band_fddlte, band->modem.v2.band_lte_ext);
        } else {
            sprintf(cmd, "serial_atcmd AT*BAND=%d,%d,%d,%d,%d", band->modem.v2.net_pref, band->modem.v2.band_gsm, band->modem.v2.band_wcdma, band->modem.v2.band_tdlte, band->modem.v2.band_fddlte);
        }
    }

    if(shell_cmd_exec(cmd, rsp, sizeof(rsp))) {
        if(strstr(rsp, "\r\nOK\r\n")) {
            return 0;
        } else {
            return -1;
        }
    } else {
        return -1;
    }
}

/*
AT*BAND=15,78,147,482,134742231

OK
*/
static int band_config(mbtk_device_info_modem_t *info_modem)
{
    if(band_set_by_at(info_modem))
    {
        return -1;
    }
    else // Set band success.
    {
        if(info_modem->modem.v2.band_area == MBTK_MODEM_BAND_AREA_CN) {
            property_set("persist.mbtk.band_config", "CN");
        } else if(info_modem->modem.v2.band_area == MBTK_MODEM_BAND_AREA_EU) {
            property_set("persist.mbtk.band_config", "EU");
        } else if(info_modem->modem.v2.band_area == MBTK_MODEM_BAND_AREA_SA) {
            property_set("persist.mbtk.band_config", "SA");
        } else {
            property_set("persist.mbtk.band_config", "ALL");
        }
//        LOGD("Set band success.");
        return 0;
    }
}

int main(int argc, char *argv[])
{
    if(argc > 1 && strcmp(argv[1], "band_set") == 0) {
        char buff[10];
        memset(buff, 0, 10);
        property_get("persist.mbtk.band_config", buff, "");
        if(strlen(buff) == 0) {
            bool band_set_success = FALSE;

            mbtk_device_info_modem_t info_modem;
            band_support_init(&info_modem);

            while(!band_set_success) {
                // Set band.
                if(band_config(&info_modem)) {
                    printf("band_config() fail,will waitting 5s to retry...\n");
                    sleep(5);
                } else {
                    break;
                }
            }
            printf("Set band success.\n");
        }
    } else {
        mbtk_device_info_basic_t info_basic;
        memset(&info_basic, 0, sizeof(mbtk_device_info_basic_t));
        int result = mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_BASIC, &info_basic, sizeof(mbtk_device_info_basic_t));
        if(result) {
            printf("mbtk_dev_info_read(BASIC) fail.\n");
            return -1;
        }

        /*
        uint8 project[16];          // T108 / L508_X6
            uint8 project_cust[16];     // T108_C1 / L508_X6_C1  (Refer to: Custom_Model in blf file.)
            uint32 ab_support;          // 1 for ab
            uint8 revision_out[48];     // L508_X6v01.01b04.00
            uint8 revision_in[64];
        */
        printf("Version:%d\n", info_basic.version);
        if(info_basic.version == DEV_INFO_VERSION_V1) {
            printf("Project:%s\n", info_basic.basic.v1.project);
            printf("Custom_Model:%s\n", info_basic.basic.v1.project_cust);
            printf("Revision_Out:%s\n", info_basic.basic.v1.revision_out);
            printf("Revision_In:%s\n", info_basic.basic.v1.revision_in);
            printf("Build_Time:%s\n", info_basic.basic.v1.build_time);
            printf("AB System:%s\n", info_basic.basic.v1.ab_support ? "Yes" : "No");
            printf("Reboot flag:%d\n", info_basic.basic.v1.reboot_flag);
        } else {
            printf("Project:%s\n", info_basic.basic.v2.project);
            printf("Custom_Model:%s\n", info_basic.basic.v2.project_cust);
            printf("Revision_Out:%s\n", info_basic.basic.v2.revision_out);
            printf("Revision_In:%s\n", info_basic.basic.v2.revision_in);
            printf("Build_Time:%s\n", info_basic.basic.v2.build_time);
            printf("AB System:%s\n", info_basic.basic.v2.ab_support ? "Yes" : "No");
            printf("Reboot flag:%d\n", info_basic.basic.v2.reboot_flag);
            printf("ASR Baseline:%s\n", info_basic.basic.v2.asr_baseline);
        }

        mbtk_device_info_modem_t info_modem;
        memset(&info_modem, 0, sizeof(mbtk_device_info_modem_t));
        result = mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_MODEM, &info_modem, sizeof(mbtk_device_info_modem_t));
        if(result) {
            printf("mbtk_dev_info_read(MODEM) fail.\n");
            return -1;
        }

        if(info_modem.version == DEV_INFO_VERSION_V1) {
            printf("Band:%s\n", band_2_str(info_modem.modem.v1.band_area));
            printf("Band GSM:0x%08x(%s)\n", info_modem.modem.v1.band_gsm, band_str_get(info_modem.modem.v1.band_gsm, 0));
            printf("Band WCDMA:0x%08x(%s)\n", info_modem.modem.v1.band_wcdma, band_str_get(info_modem.modem.v1.band_wcdma, 0));
            printf("Band TDLTE:0x%08x(%s)\n", info_modem.modem.v1.band_tdlte, band_str_get(info_modem.modem.v1.band_tdlte, 1));
            printf("Band FDDLTE:0x%08x(%s)\n", info_modem.modem.v1.band_fddlte, band_str_get(info_modem.modem.v1.band_fddlte, 0));
            printf("Band EXT_LTE:0x%08x(%s)\n", info_modem.modem.v1.band_lte_ext, band_str_get(info_modem.modem.v1.band_lte_ext, 0));
        } else {
            printf("net_pref:%d\n", info_modem.modem.v2.net_pref);
            printf("net_support:%s\n", net_support_str_get(info_modem.modem.v2.net_support));
            printf("Band:%s\n", band_2_str(info_modem.modem.v2.band_area));
            printf("Band GSM:0x%08x(%s)\n", info_modem.modem.v2.band_gsm, band_str_get(info_modem.modem.v2.band_gsm, 0));
            printf("Band WCDMA:0x%08x(%s)\n", info_modem.modem.v2.band_wcdma, band_str_get(info_modem.modem.v2.band_wcdma, 0));
            printf("Band TDLTE:0x%08x(%s)\n", info_modem.modem.v2.band_tdlte, band_str_get(info_modem.modem.v2.band_tdlte, 1));
            printf("Band FDDLTE:0x%08x(%s)\n", info_modem.modem.v2.band_fddlte, band_str_get(info_modem.modem.v2.band_fddlte, 0));
            printf("Band EXT_LTE:0x%08x(%s)\n", info_modem.modem.v2.band_lte_ext, band_str_get(info_modem.modem.v2.band_lte_ext, 0));
            printf("Band NR_3:0x%08x(%s)\n", info_modem.modem.v2.band_nr_3, band_str_get(info_modem.modem.v2.band_nr_3, 3));
            printf("Band NR_2:0x%08x(%s)\n", info_modem.modem.v2.band_nr_2, band_str_get(info_modem.modem.v2.band_nr_2, 2));
            printf("Band NR_1:0x%08x(%s)\n", info_modem.modem.v2.band_nr_1, band_str_get(info_modem.modem.v2.band_nr_1, 1));
            printf("Band NR_0:0x%08x(%s)\n", info_modem.modem.v2.band_nr_0, band_str_get(info_modem.modem.v2.band_nr_0, 0));
        }
    }
    return 0;
}


