/*
 * Copyright (C) 2015 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 <phNxpConfig.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <list>
#include <sys/stat.h>

#include <phNxpLog.h>

#if GENERIC_TARGET
const char alternative_config_path[] = "/data/nfc/";
#else
const char alternative_config_path[] = "";
#endif

#if 1
const char transport_config_path[] = "/etc/";
#else
const char transport_config_path[] = "res/";
#endif

#define config_name             "libnfc-nxp.conf"
#define extra_config_base       "libnfc-nxp-"
#define extra_config_ext        ".conf"
#define IsStringValue           0x80000000

const char config_timestamp_path[] = "/data/nfc/libnfc-nxpConfigState.bin";

using namespace::std;

class CNxpNfcParam : public string
{
public:
    CNxpNfcParam ();
    CNxpNfcParam (const char* name, const string& value);
    CNxpNfcParam (const char* name, unsigned long value);
    virtual ~CNxpNfcParam ();
    unsigned long numValue () const {return m_numValue;}
    const char* str_value () const {return m_str_value.c_str();}
    size_t str_len () const {return m_str_value.length();}
private:
    string          m_str_value;
    unsigned long   m_numValue;
};

class CNxpNfcConfig : public vector<const CNxpNfcParam*>
{
public:
    virtual ~CNxpNfcConfig ();
    static CNxpNfcConfig& GetInstance ();
    friend void readOptionalConfig (const char* optional);
    int checkTimestamp ();

    bool    getValue (const char* name, char* pValue, size_t len) const;
    bool    getValue (const char* name, unsigned long& rValue) const;
    bool    getValue (const char* name, unsigned short & rValue) const;
    bool    getValue (const char* name, char* pValue, long len, long* readlen) const;
    const CNxpNfcParam* find (const char* p_name) const;
    void  clean ();
private:
    CNxpNfcConfig ();
    bool    readConfig (const char* name, bool bResetContent);
    void    moveFromList ();
    void    moveToList ();
    void    add (const CNxpNfcParam* pParam);
    list<const CNxpNfcParam*> m_list;
    bool    mValidFile;
    unsigned long m_timeStamp;

    unsigned long state;

    inline bool Is (unsigned long f) {return (state & f) == f;}
    inline void Set (unsigned long f) {state |= f;}
    inline void Reset (unsigned long f) {state &= ~f;}
};

/*******************************************************************************
**
** Function:    isPrintable()
**
** Description: determine if 'c' is printable
**
** Returns:     1, if printable, otherwise 0
**
*******************************************************************************/
inline bool isPrintable (char c)
{
    return  (c >= 'A' && c <= 'Z') ||
            (c >= 'a' && c <= 'z') ||
            (c >= '0' && c <= '9') ||
            c == '/' || c == '_' || c == '-' || c == '.';
}

/*******************************************************************************
**
** Function:    isDigit()
**
** Description: determine if 'c' is numeral digit
**
** Returns:     true, if numerical digit
**
*******************************************************************************/
inline bool isDigit (char c, int base)
{
    if ('0' <= c && c <= '9')
        return true;
    if (base == 16)
    {
        if (('A' <= c && c <= 'F') ||
            ('a' <= c && c <= 'f'))
            return true;
    }
    return false;
}

/*******************************************************************************
**
** Function:    getDigitValue()
**
** Description: return numerical value of a decimal or hex char
**
** Returns:     numerical value if decimal or hex char, otherwise 0
**
*******************************************************************************/
inline int getDigitValue (char c, int base)
{
    if ('0' <= c && c <= '9')
        return c - '0';
    if (base == 16)
    {
        if ('A' <= c && c <= 'F')
            return c - 'A' + 10;
        else if ('a' <= c && c <= 'f')
            return c - 'a' + 10;
    }
    return 0;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::readConfig()
**
** Description: read Config settings and parse them into a linked list
**              move the element from linked list to a array at the end
**
** Returns:     1, if there are any config data, 0 otherwise
**
*******************************************************************************/
bool CNxpNfcConfig::readConfig (const char* name, bool bResetContent)
{
    enum {
        BEGIN_LINE = 1,
        TOKEN,
        STR_VALUE,
        NUM_VALUE,
        BEGIN_HEX,
        BEGIN_QUOTE,
        END_LINE
    };

    FILE*   fd;
    struct stat buf;
    string  token;
    string  strValue;
    unsigned long    numValue = 0;
    CNxpNfcParam* pParam = NULL;
    int     i = 0;
    int     base = 0;
    char    c;
    int     bflag = 0;
    state = BEGIN_LINE;
    /* open config file, read it into a buffer */
    if ((fd = fopen (name, "rb")) == NULL)
    {
        ALOGE ("%s Cannot open config file %s\n", __func__, name);
        if (bResetContent)
        {
            ALOGE ("%s Using default value for all settings\n", __func__);
            mValidFile = false;
        }
        return false;
    }
    stat (name, &buf);
    m_timeStamp = (unsigned long) buf.st_mtime;

    mValidFile = true;
    if (size() > 0)
    {
        if (bResetContent)
            clean ();
        else
            moveToList ();
    }

    while (!feof (fd) && fread (&c, 1, 1, fd) == 1)
    {
        switch (state & 0xff)
        {
        case BEGIN_LINE:
            if (c == '#')
            {
                state = END_LINE;
            }
            else if (isPrintable (c))
            {
                i = 0;
                token.erase ();
                strValue.erase ();
                state = TOKEN;
                token.push_back (c);
            }
            break;
        case TOKEN:
            if (c == '=')
            {
                token.push_back ('\0');
                state = BEGIN_QUOTE;
            }
            else if (isPrintable (c))
            {
                token.push_back (c);
            }
            else
            {
                state = END_LINE;
            }
            break;
        case BEGIN_QUOTE:
            if (c == '"')
            {
                state = STR_VALUE;
                base = 0;
            }
            else if (c == '0')
            {
                state = BEGIN_HEX;
            }
            else if (isDigit (c, 10))
            {
                state = NUM_VALUE;
                base = 10;
                numValue = getDigitValue (c, base);
                i = 0;
            }
            else if (c == '{')
            {
                state = NUM_VALUE;
                bflag = 1;
                base = 16;
                i = 0;
                Set (IsStringValue);
            }
            else
                state = END_LINE;

            break;
        case BEGIN_HEX:
            if (c == 'x' || c == 'X')
            {
                state = NUM_VALUE;
                base = 16;
                numValue = 0;
                i = 0;
                break;
            }
            else if (isDigit (c, 10))
            {
                state = NUM_VALUE;
                base = 10;
                numValue = getDigitValue (c, base);
                break;
            }
            else if (c != '\n' && c != '\r')
            {
                state = END_LINE;
                break;
            }
            // fall through to numValue to handle numValue

        case NUM_VALUE:
            if (isDigit (c, base))
            {
                numValue *= base;
                numValue += getDigitValue (c, base);
                ++i;
            }
            else if(bflag == 1 && (c == ' ' || c == '\r' || c=='\n' || c=='\t'))
            {
                break;
            }
            else if (base == 16 && (c== ','|| c == ':' || c == '-' || c == ' ' || c == '}'))
            {

                if( c=='}' )
                {
                    bflag = 0;
                }
                if (i > 0)
                {
                    int n = (i+1) / 2;
                    while (n-- > 0)
                    {
                        numValue = numValue >> (n * 8);
                        unsigned char c = (numValue) & 0xFF;
                        strValue.push_back (c);
                    }
                }

                Set (IsStringValue);
                numValue = 0;
                i = 0;
            }
            else
            {
                if (c == '\n' || c == '\r')
                {
                    if (bflag == 0)
                    {
                        state = BEGIN_LINE;
                    }
                }
                else
                {
                    if (bflag == 0)
                    {
                        state = END_LINE;
                    }
                }
                if (Is (IsStringValue) && base == 16 && i > 0)
                {
                    int n = (i+1) / 2;
                    while (n-- > 0)
                        strValue.push_back (((numValue >> (n * 8)) & 0xFF));
                }
                if (strValue.length() > 0)
                    pParam = new CNxpNfcParam (token.c_str (), strValue);
                else
                    pParam = new CNxpNfcParam (token.c_str (), numValue);

                add (pParam);
                strValue.erase ();
                numValue = 0;
            }
            break;
        case STR_VALUE:
            if (c == '"')
            {
                strValue.push_back('\0');
                state = END_LINE;
                pParam = new CNxpNfcParam(token.c_str(), strValue);
                add(pParam);
            }
            else if (isPrintable(c))
            {
                strValue.push_back(c);
            }
            break;
        case END_LINE:
            if (c == '\n' || c == '\r')
            {
                state = BEGIN_LINE;
            }
            break;
        default:
            break;
        }
    }

    fclose (fd);

    moveFromList ();
    return size () > 0;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::CNxpNfcConfig()
**
** Description: class constructor
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcConfig::CNxpNfcConfig () :
    mValidFile (true),
    m_timeStamp (0),
    state (0)
{
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::~CNxpNfcConfig()
**
** Description: class destructor
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcConfig::~CNxpNfcConfig ()
{
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::GetInstance()
**
** Description: get class singleton object
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcConfig& CNxpNfcConfig::GetInstance ()
{
    static CNxpNfcConfig theInstance;

    if (theInstance.size () == 0 && theInstance.mValidFile)
    {
        string strPath;
        if (alternative_config_path [0] != '\0')
        {
            strPath.assign (alternative_config_path);
            strPath += config_name;
            theInstance.readConfig (strPath.c_str (), true);
            if (!theInstance.empty ())
            {
                return theInstance;
            }
        }
        strPath.assign (transport_config_path);
        strPath += config_name;
        theInstance.readConfig (strPath.c_str (), true);
    }

    return theInstance;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::getValue()
**
** Description: get a string value of a setting
**
** Returns:     true if setting exists
**              false if setting does not exist
**
*******************************************************************************/
bool CNxpNfcConfig::getValue (const char* name, char* pValue, size_t len) const
{
    const CNxpNfcParam* pParam = find (name);
    if (pParam == NULL)
        return false;

    if (pParam->str_len () > 0)
    {
        memset (pValue, 0, len);
        memcpy (pValue, pParam->str_value (), pParam->str_len ());
        return true;
    }
    return false;
}

bool CNxpNfcConfig::getValue (const char* name, char* pValue, long len,long* readlen) const
{
    const CNxpNfcParam* pParam = find (name);
    if (pParam == NULL)
        return false;

    if (pParam->str_len () > 0)
    {
        if(pParam->str_len () <= (unsigned long) len)
        {
            memset (pValue, 0, len);
            memcpy (pValue, pParam->str_value (), pParam->str_len ());
            *readlen = pParam->str_len ();
        }
        else
        {
            *readlen = -1;
        }

        return true;
    }
    return false;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::getValue()
**
** Description: get a long numerical value of a setting
**
** Returns:     true if setting exists
**              false if setting does not exist
**
*******************************************************************************/
bool CNxpNfcConfig::getValue (const char* name, unsigned long& rValue) const
{
    const CNxpNfcParam* pParam = find (name);
    if (pParam == NULL)
        return false;

    if (pParam->str_len () == 0)
    {
        rValue = static_cast<unsigned long> (pParam->numValue ());
        return true;
    }
    return false;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::getValue()
**
** Description: get a short numerical value of a setting
**
** Returns:     true if setting exists
**              false if setting does not exist
**
*******************************************************************************/
bool CNxpNfcConfig::getValue (const char* name, unsigned short& rValue) const
{
    const CNxpNfcParam* pParam = find (name);
    if (pParam == NULL)
        return false;

    if (pParam->str_len () == 0)
    {
        rValue = static_cast<unsigned short> (pParam->numValue ());
        return true;
    }
    return false;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::find()
**
** Description: search if a setting exist in the setting array
**
** Returns:     pointer to the setting object
**
*******************************************************************************/
const CNxpNfcParam* CNxpNfcConfig::find (const char* p_name) const
{
    if (size () == 0)
        return NULL;

    for (const_iterator it = begin (), itEnd = end (); it != itEnd; ++it)
    {
        if (**it < p_name)
        {
            continue;
        }
        else if (**it == p_name)
        {
            if ((*it)->str_len () > 0)
            {
                NXPLOG_EXTNS_D ("%s found %s=%s\n", __func__, p_name, (*it)->str_value());
            }
            else
            {
                NXPLOG_EXTNS_D ("%s found %s=(0x%lx)\n", __func__, p_name, (*it)->numValue());
            }
            return *it;
        }
        else
            break;
    }
    return NULL;
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::clean()
**
** Description: reset the setting array
**
** Returns:     none
**
*******************************************************************************/
void CNxpNfcConfig::clean ()
{
    if (size () == 0)
        return;

    for (iterator it = begin (), itEnd = end (); it != itEnd; ++it)
        delete *it;

    clear ();
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::Add()
**
** Description: add a setting object to the list
**
** Returns:     none
**
*******************************************************************************/
void CNxpNfcConfig::add (const CNxpNfcParam* pParam)
{
    if (m_list.size () == 0)
    {
        m_list.push_back (pParam);
        return;
    }
    for (list<const CNxpNfcParam*>::iterator it = m_list.begin (), itEnd = m_list.end (); it != itEnd; ++it)
    {
        if (**it < pParam->c_str ())
            continue;

        m_list.insert (it, pParam);
        return;
    }
    m_list.push_back (pParam);
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::moveFromList()
**
** Description: move the setting object from list to array
**
** Returns:     none
**
*******************************************************************************/
void CNxpNfcConfig::moveFromList ()
{
    if (m_list.size () == 0)
        return;

    for (list<const CNxpNfcParam*>::iterator it = m_list.begin (), itEnd = m_list.end (); it != itEnd; ++it)
        push_back (*it);

    m_list.clear ();
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::moveToList()
**
** Description: move the setting object from array to list
**
** Returns:     none
**
*******************************************************************************/
void CNxpNfcConfig::moveToList ()
{
    if (m_list.size () != 0)
        m_list.clear ();

    for (iterator it = begin (), itEnd = end (); it != itEnd; ++it)
        m_list.push_back (*it);

    clear();
}

/*******************************************************************************
**
** Function:    CNxpNfcConfig::checkTimestamp()
**
** Description: check if config file has modified
**
** Returns:     0 if not modified, 1 otherwise.
**
*******************************************************************************/
int CNxpNfcConfig::checkTimestamp ()
{
    FILE* fd;
    struct stat st;
    unsigned long value = 0;
    int ret = 0;

    if (stat(config_timestamp_path, &st) != 0)
    {
        ALOGD ("%s file %s not exist, creat it.\n", __func__, config_timestamp_path);
        if ((fd = fopen (config_timestamp_path, "w+")) != NULL)
        {
            fwrite (&m_timeStamp, sizeof(unsigned long), 1, fd);
            fclose (fd);
        }
        return 1;
    }
    else
    {
        fd = fopen (config_timestamp_path, "r+");
        if (fd == NULL)
        {
            ALOGE ("%s Cannot open file %s\n", __func__, config_timestamp_path);
            return 1;
        }

        fread (&value, sizeof(unsigned long), 1, fd);
        ret = (value != m_timeStamp);
        if (ret)
        {
            fseek (fd, 0, SEEK_SET);
            fwrite (&m_timeStamp, sizeof(unsigned long), 1, fd);
        }
        fclose (fd);
    }
    return ret;
}

/*******************************************************************************
**
** Function:    CNxpNfcParam::CNxpNfcParam()
**
** Description: class constructor
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcParam::CNxpNfcParam () :
    m_numValue (0)
{
}

/*******************************************************************************
**
** Function:    CNxpNfcParam::~CNxpNfcParam()
**
** Description: class destructor
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcParam::~CNxpNfcParam ()
{
}

/*******************************************************************************
**
** Function:    CNxpNfcParam::CNxpNfcParam()
**
** Description: class copy constructor
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcParam::CNxpNfcParam (const char* name, const string& value) :
    string (name),
    m_str_value (value),
    m_numValue (0)
{
}

/*******************************************************************************
**
** Function:    CNxpNfcParam::CNxpNfcParam()
**
** Description: class copy constructor
**
** Returns:     none
**
*******************************************************************************/
CNxpNfcParam::CNxpNfcParam (const char* name, unsigned long value) :
    string (name),
    m_numValue (value)
{
}

/*******************************************************************************
**
** Function:    GetStrValue
**
** Description: API function for getting a string value of a setting
**
** Returns:     True if found, otherwise False.
**
*******************************************************************************/
extern "C" int GetNxpStrValue (const char* name, char* pValue, unsigned long len)
{
    CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance ();

    return rConfig.getValue (name, pValue, len);
}

/*******************************************************************************
**
** Function:    GetByteArrayValue()
**
** Description: Read byte array value from the config file.
**
** Parameters:
**              name    - name of the config param to read.
**              pValue  - pointer to input buffer.
**              bufflen - input buffer length.
**              len     - out parameter to return the number of bytes read from config file,
**                        return -1 in case bufflen is not enough.
**
** Returns:     TRUE[1] if config param name is found in the config file, else FALSE[0]
**
*******************************************************************************/
extern "C" int GetNxpByteArrayValue (const char* name, char* pValue, long bufflen, long *len)
{
    CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance ();

    return rConfig.getValue (name, pValue, bufflen,len);
}

/*******************************************************************************
**
** Function:    GetNumValue
**
** Description: API function for getting a numerical value of a setting
**
** Returns:     true, if successful
**
*******************************************************************************/
extern "C" int GetNxpNumValue (const char* name, void* pValue, unsigned long len)
{
    if (!pValue)
        return false;

    CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance ();
    const CNxpNfcParam* pParam = rConfig.find (name);

    if (pParam == NULL)
        return false;

    unsigned long v = pParam->numValue ();
    if (v == 0 && pParam->str_len () > 0 && pParam->str_len () < 4)
    {
        const unsigned char* p = (const unsigned char*) pParam->str_value ();
        for (unsigned int i = 0 ; i < pParam->str_len (); ++i)
        {
            v *= 256;
            v += *p++;
        }
    }
    switch (len)
    {
    case sizeof(unsigned long):
        *(static_cast<unsigned long*>(pValue)) = (unsigned long) v;
        break;
    case sizeof(unsigned short):
        *(static_cast<unsigned short*>(pValue)) = (unsigned short) v;
        break;
    case sizeof(unsigned char):
        *(static_cast<unsigned char*> (pValue)) = (unsigned char) v;
        break;
    default:
        return false;
    }
    return true;
}

/*******************************************************************************
**
** Function:    resetConfig
**
** Description: reset settings array
**
** Returns:     none
**
*******************************************************************************/
extern "C" void resetNxpConfig ()
{
    CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance ();

    rConfig.clean ();
}

/*******************************************************************************
**
** Function:    readOptionalConfig()
**
** Description: read Config settings from an optional conf file
**
** Returns:     none
**
*******************************************************************************/
void readOptionalConfig (const char* extra)
{
    string strPath;
    strPath.assign (transport_config_path);
    if (alternative_config_path [0] != '\0')
        strPath.assign (alternative_config_path);

    strPath += extra_config_base;
    strPath += extra;
    strPath += extra_config_ext;
    CNxpNfcConfig::GetInstance ().readConfig (strPath.c_str (), false);
}

/*******************************************************************************
**
** Function:    isNxpConfigModified()
**
** Description: check if config file has modified
**
** Returns:     0 if not modified, 1 otherwise.
**
*******************************************************************************/
extern "C" int isNxpConfigModified ()
{
    CNxpNfcConfig& rConfig = CNxpNfcConfig::GetInstance ();
    return rConfig.checkTimestamp ();
}
