/*
 * Copyright (C) 2013-2017 Intel Corporation
 * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
 *
 * 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 "Profiles"

#include <expat.h>
#include <limits.h>
#include <system/camera_metadata.h>

#include "LogHelper.h"
#include "CameraProfiles.h"
#include "Metadata.h"
#include "CameraMetadataHelper.h"
#include "IPSLConfParser.h"
#include "Utils.h"

#include "PSLConfParser.h"

/**
 * Platform specific implementation
 */
#include "ChromeCameraProfiles.h"

#define STATIC_ENTRY_CAP 256
#define STATIC_DATA_CAP 6688 // TODO: we may need to increase it again if more metadata is added
#define MAX_METADATA_NAME_LENTGTH 128
#define MAX_METADATA_ATTRIBUTE_NAME_LENTGTH 128
#define MAX_METADATA_ATTRIBUTE_VALUE_LENTGTH 6144

NAMESPACE_DECLARATION {
CameraProfiles::CameraProfiles(CameraHWInfo *cameraHWInfo) :
    mCurrentDataField(FIELD_INVALID),
    mMetadataCache(nullptr),
    mSensorIndex(-1),
    mXmlSensorIndex(-1),
    mItemsCount(-1),
    mCameraCommon(cameraHWInfo),
    mUseEntry(true)
{
    CLEAR(mProfileEnd);
}

status_t CameraProfiles::init()
{
    LOG1("@%s", __FUNCTION__);

    if (!mCameraCommon) {
        LOGE("CameraHWInfo is nullptr");
        return BAD_VALUE;
    }

    mCameraCommon->init(PSLConfParser::getSensorMediaDevicePath());

    // Assumption: Driver enumeration order will match the CameraId
    // CameraId in camera_profiles.xml. Main camera is always at
    // index 0, front camera at index 1.
    if (mCameraCommon->mSensorInfo.empty()) {
        LOGE("No sensor Info available, exit parsing");
        return UNKNOWN_ERROR;
    }

    mSensorNames = mCameraCommon->mSensorInfo;

    mCameraInfoPool.init(MAX_CAMERAS);
    for (int i = 0;i < MAX_CAMERAS; i++)
         mCharacteristicsKeys[i].clear();

    return OK;
}

void CameraProfiles::createConfParser()
{
    // Now parse PSL sections for found cameras
    for (const auto &cameraIdToCameraInfo : mCameraIdToCameraInfo) {
        // get psl parser
        CameraInfo *info = cameraIdToCameraInfo.second;
        info->parser = PSLConfParser::getInstance(mXmlConfigName, mSensorNames);
    }
}

void CameraProfiles::destroyConfParser()
{
    PSLConfParser::deleteInstance();
}

int CameraProfiles::getXmlCameraId(int cameraId) const
{
    LOG2("@%s", __FUNCTION__);
    std::map<int, CameraInfo*>::const_iterator it =
                            mCameraIdToCameraInfo.find(cameraId);
    if (it == mCameraIdToCameraInfo.end()) {
        return NAME_NOT_FOUND;
    }
    return it->second->xmlCameraId;
}

CameraProfiles::~CameraProfiles()
{
    LOG2("@%s", __FUNCTION__);
    for (unsigned int i = 0; i < mStaticMeta.size(); i++) {
        if (mStaticMeta[i])
            free_camera_metadata(mStaticMeta[i]);
    }

    mStaticMeta.clear();

    for (const auto &cameraIdToCameraInfo : mCameraIdToCameraInfo) {
        CameraInfo *info = cameraIdToCameraInfo.second;
        mCameraInfoPool.releaseItem(info);
    }

    mCameraIdToCameraInfo.clear();

    mSensorNames.clear();
}

const CameraCapInfo *CameraProfiles::getCameraCapInfo(int cameraId)
{
    // get the psl parser instance for cameraid
    IPSLConfParser *parserInstance;
    std::map<int, CameraInfo*>::iterator it =
                            mCameraIdToCameraInfo.find(cameraId);
    if (it == mCameraIdToCameraInfo.end()) {
        LOGE("Camera id: %d not found. Sensor might not be live", cameraId);
        return nullptr;
    }
    CameraInfo *info = it->second;
    parserInstance = info->parser;

    if (parserInstance == nullptr) {
        LOGE("Failed to get PSL parser instance");
        return nullptr;
    }

    return parserInstance->getCameraCapInfo(cameraId);
}

const CameraCapInfo *CameraProfiles::getCameraCapInfoForXmlCameraId(int xmlCameraId)
{
    // get the psl parser instance for cameraid
    IPSLConfParser *parserInstance;

    int cameraId = -1;
    for (const auto &cameraIdToCameraInfo : mCameraIdToCameraInfo) {
        if (cameraIdToCameraInfo.second->xmlCameraId == xmlCameraId) {
            cameraId = cameraIdToCameraInfo.first;
            break;
        }
    }
    if (cameraId == -1)
        return nullptr;

    CameraInfo *info = mCameraIdToCameraInfo[cameraId];
    parserInstance = info->parser;

    if (parserInstance == nullptr) {
        LOGE("Failed to get PSL parser instance");
        return nullptr;
    }

    return parserInstance->getCameraCapInfo(cameraId);
}

camera_metadata_t *CameraProfiles::constructDefaultMetadata(int cameraId, int requestTemplate)
{
    // get the psl parser instance for cameraid
    IPSLConfParser *parserInstance;
    std::map<int, CameraInfo*>::iterator it =
                            mCameraIdToCameraInfo.find(cameraId);
    if (it == mCameraIdToCameraInfo.end()) {
        LOGE("Failed to get camera info for camera:%d", cameraId);
        return nullptr;
    }

    CameraInfo *info = it->second;
    parserInstance = info->parser;

    if (parserInstance == nullptr) {
        LOGE("Failed to get PSL parser instance");
        return nullptr;
    }

    return parserInstance->constructDefaultMetadata(cameraId, requestTemplate);

}

status_t CameraProfiles::addCamera(int cameraId)
{
    LOG1("%s: for camera %d", __FUNCTION__, cameraId);

    camera_metadata_t * meta = allocate_camera_metadata(STATIC_ENTRY_CAP, STATIC_DATA_CAP);
    if (!meta) {
        LOGE("No memory for camera metadata!");
        return NO_MEMORY;
    }
    LOG2("Add cameraId: %d to mStaticMeta", cameraId);
    mStaticMeta.push_back(meta);

    return NO_ERROR;
}

/**
 * convertEnum
 * Converts from the string provided as src to an enum value.
 * It uses a table to convert from the string to an enum value (usually BYTE)
 * \param [IN] dest: data buffer where to store the result
 * \param [IN] src: pointer to the string to parse
 * \param [IN] table: table to convert from string to value
 * \param [IN] tableNum: size of the enum table
 * \param [IN] type: data type to be parsed (byte, int32, int64 etc..)
 * \param [OUT] newDest: pointer to the new write location
 */
int CameraProfiles::convertEnum(void *dest, const char *src, int type,
                                const metadata_value_t *table, int tableLen,
                                void **newDest)
{
    int ret = 0;
    union {
        uint8_t * u8;
        int32_t * i32;
        int64_t * i64;
    } data;

    *newDest = dest;
    data.u8 = (uint8_t *)dest;

    /* ignore any spaces in front of the string */
    size_t blanks = strspn(src," ");
    src = src + blanks;

    for (int i = 0; i < tableLen; i++ ) {
        if (!strncasecmp(src, table[i].name, STRLEN_S(table[i].name))
            && (STRLEN_S(src) == STRLEN_S(table[i].name))) {
            if (type == TYPE_BYTE) {
                data.u8[0] = table[i].value;
                LOG1("byte    - %s: %d -", table[i].name, data.u8[0]);
                *newDest = (void*) &data.u8[1];
            } else if (type == TYPE_INT32) {
                data.i32[0] = table[i].value;
                LOG1("int    - %s: %d -", table[i].name, data.i32[0]);
                *newDest = (void*) &data.i32[1];
            } else if (type == TYPE_INT64) {
                data.i64[0] = table[i].value;
                LOG1("int64    - %s: %" PRId64 " -", table[i].name, data.i64[0]);
                *newDest = (void*) &data.i64[1];
            }
            ret = 1;
            break;
        }
    }

    return ret;
}


/**
 * parseEnum
 * parses an enumeration type or a list of enumeration types it stores the data
 * in the member buffer mMetadataCache that is of size mMetadataCacheSize.
 *
 * \param src: string to be parsed
 * \param tagInfo: structure with the description of the static metadata
 * \param metadataCacheSize:the upper limited size of the dest buffer
 * \param metadataCache: the dest buffer to store the medatada after persed
 * \return number of elements parsed
 */
int CameraProfiles::parseEnum(const char *src,
                              const metadata_tag_t *tagInfo,
                              int metadataCacheSize,
                              int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);
    int count = 0;
    int maxCount = metadataCacheSize / camera_metadata_type_size[tagInfo->type];
    char *endPtr = nullptr;

    /**
     * pointer to the metadata cache buffer
     */
    void *storeBuf = metadataCache;
    void *next;

    do {
        endPtr = (char*) strchr(src, ',');
        if (endPtr)
            *endPtr = 0;

        count += convertEnum(storeBuf, src,tagInfo->type,
                             tagInfo->enumTable, tagInfo->tableLength, &next);
        if (endPtr) {
            src = endPtr + 1;
            storeBuf = next;
        }
    } while (count < maxCount && endPtr);

    return count;
}

/**
 * parseEnumAndNumbers
 * parses an enumeration type or a list of enumeration types or tries to convert string to a number
 * it stores the data in the member buffer mMetadataCache that is of size mMetadataCacheSize.
 *
 * \param src: string to be parsed
 * \param tagInfo: structure with the description of the static metadata
  * \param metadataCacheSize:the upper limited size of the dest buffer
 * \param metadataCache: the dest buffer to store the medatada after persed
 * \return number of elements parsed
 */
int CameraProfiles::parseEnumAndNumbers(const char *src,
                                        const metadata_tag_t *tagInfo,
                                        int metadataCacheSize,
                                        int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);
    int count = 0;
    int maxCount = metadataCacheSize / camera_metadata_type_size[tagInfo->type];
    char * endPtr = nullptr;

    /**
     * pointer to the metadata cache buffer
     */
    void *storeBuf = metadataCache;
    void *next;

    do {
        endPtr = (char *) strchr(src, ',');
        if (endPtr)
            *endPtr = 0;

        count += convertEnum(storeBuf, src,tagInfo->type,
                             tagInfo->enumTable, tagInfo->tableLength, &next);
        /* Try to convert value to number */
        if (count == 0) {
            long int *number = reinterpret_cast<long int*>(storeBuf);
            *number = strtol(src, &endPtr, 10);
            if (*number == LONG_MAX || *number == LONG_MIN)
                LOGW("You might have invalid value in the camera profiles: %s", src);
            count++;
        }

        if (endPtr) {
            src = endPtr + 1;
            storeBuf = next;
        }
    } while (count < maxCount && endPtr);

    return count;
}

/**
 * parseData
 * parses a generic array type. It stores the data in the member buffer
 * mMetadataCache that is of size mMetadataCacheSize.
 *
 * \param src: string to be parsed
 * \param tagInfo: structure with the description of the static metadata
 * \param metadataCacheSize:the upper limited size of the dest buffer
 * \param metadataCache: the dest buffer to store the medatada after persed
 * \return number of elements parsed
 */
int CameraProfiles::parseData(const char *src,
                              const metadata_tag_t *tagInfo,
                              int metadataCacheSize,
                              int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);
    int index = 0;
    int maxIndex = metadataCacheSize/sizeof(double); // worst case

    char * endPtr = nullptr;
    union {
        uint8_t * u8;
        int32_t * i32;
        int64_t * i64;
        float * f;
        double * d;
    } data;
    data.u8 = (uint8_t *)metadataCache;

    do {
        switch (tagInfo->type) {
        case TYPE_BYTE:
            data.u8[index] = (char)strtol(src, &endPtr, 10);
            LOG2("    - %d -", data.u8[index]);
            break;
        case TYPE_INT32:
        case TYPE_RATIONAL:
            data.i32[index] = strtol(src, &endPtr, 10);
            LOG2("    - %d -", data.i32[index]);
            break;
        case TYPE_INT64:
            data.i64[index] = strtol(src, &endPtr, 10);
            LOG2("    - %" PRId64 " -", data.i64[index]);
            break;
        case TYPE_FLOAT:
            data.f[index] = strtof(src, &endPtr);
            LOG2("    - %8.3f -", data.f[index]);
            break;
        case TYPE_DOUBLE:
            data.d[index] = strtof(src, &endPtr);
            LOG2("    - %8.3f -", data.d[index]);
            break;
        }
        index++;
        if (endPtr != nullptr) {
            if (*endPtr == ',' || *endPtr == 'x')
                src = endPtr + 1;
            else if (*endPtr == ')')
                src = endPtr + 3;
            else if (*endPtr == 0)
                break;
        }
    } while (index < maxIndex);

    if (tagInfo->type == TYPE_RATIONAL) {
        if (index % 2) {
            LOGW("Invalid number of entries to define rational (%d) in tag %s."
                            " It should be even", index, tagInfo->name);
            // lets make it even
            index -= 1;
        }
        index = index / 2;
        // we divide by 2 because one rational is made of 2 ints
    }

    return index;
}


const char *CameraProfiles::skipWhiteSpace(const char *src)
{
    /* Skip whitespace. (space, tab, newline, vertical tab, feed, carriage return) */
    while( *src == '\n' || *src == '\t' || *src == ' ' || *src == '\v' || *src == '\r' || *src == '\f'  ) {
        src++;
    }
    return src;
}

/**
 * Parses the string with the supported stream configurations
 * a stream configuration is made of 3 elements
 * - Format
 * - Resolution
 * - Direction (input or output)
 * we parse the string in 3 steps
 * example of valid stream configuration is:
 * RAW16,4208x3120,INPUT
 * \param src: string to be parsed
 * \param tagInfo: descriptor of the static metadata. this is the entry from the
 * table defined in the autogenerated code
 * \param metadataCacheSize:the upper limited size of the dest buffer
 * \param metadataCache: the dest buffer to store the medatada after persed
 *
 * \return number of int32 entries to be stored (i.e. 4 per configuration found)
 */
int CameraProfiles::parseStreamConfig(const char *src,
        const metadata_tag_t *tagInfo,
        std::vector<MetaValueRefTable> refTables,
        int metadataCacheSize,
        int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);

    int count = 0;  // entry count
    int maxCount = metadataCacheSize/sizeof(int32_t);
    int ret;
    char * endPtr = nullptr;
    int parseStep = 1;
    int32_t *i32;

    const metadata_value_t * activeTable;
    int activeTableLen = 0;

    void *storeBuf = metadataCache;
    void *next;

    if (refTables.size() < 2) {
        LOGE("incomplete reference table :%zu", refTables.size());
        return count;
    }

    do {
        endPtr = (char *) strchr(src, ',');
        if (endPtr)
            *endPtr = 0;

        if (parseStep == 1) {
            activeTable = refTables[0].table;
            activeTableLen = refTables[0].tableSize;
        } else if (parseStep == 3) {
            activeTable = refTables[1].table;
            activeTableLen = refTables[1].tableSize;
        }

        if (parseStep == 1 || parseStep == 3) {
            ret = convertEnum(storeBuf, src, tagInfo->type, activeTable,
                              activeTableLen, &next);
            if (ret == 1) {
                count++;
                storeBuf = next;
            } else {
                LOGE("Malformed enum in stream configuration %s", src);
                goto parseError;
            }

        } else {  // Step 2: Parse the resolution
            i32 = reinterpret_cast<int32_t*>(storeBuf);
            i32[0] = strtol(src, &endPtr, 10);
            if (endPtr == nullptr || *endPtr != 'x') {
                LOGE("Malformed resolution in stream configuration");
                goto parseError;
            }
            src = endPtr + 1;
            i32[1] = strtol(src, &endPtr, 10);
            storeBuf = reinterpret_cast<void*>(&i32[2]);
            count += 2;
            LOG1("  - %dx%d -", i32[0], i32[1]);
        }

        if (endPtr) {
            src = endPtr + 1;
            src = skipWhiteSpace(src);
            parseStep++;
            /* parsing steps go from 1 to 3 */
            if (parseStep == 4) {
                parseStep = 1;
                LOG1("Stream Configuration found");
            }
        } else {
            break;
        }
    } while (count < maxCount);

    if (endPtr != nullptr) {
        LOGW("Stream configuration stream too long for parser");
    }
    /**
     * Total number of entries per stream configuration is 4
     * - one for the format
     * - two for the resolution
     * - one for the direction
     * The total entry count should be multiple of 4
     */
    if (count % 4) {
        LOGE("Malformed string for stream configuration."
             " ignoring last %d entries", count % 4);
        count -= count % 4;
    }
    return count;

parseError:
    LOGE("Error parsing stream configuration ");
    return 0;
}
/**
 * parseAvailableKeys
 * This method is used to parse the following two static metadata tags:
 * android.request.availableRequestKeys
 * android.request.availableResultKeys
 *
 * It uses the auto-generated table metadataNames to look for all the non
 * static tags.
 */
int CameraProfiles::parseAvailableKeys(const char *src,
                                       const metadata_tag_t *tagInfo,
                                       int metadataCacheSize,
                                       int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);
    int count = 0;  // entry count
    int maxCount = metadataCacheSize/camera_metadata_type_size[tagInfo->type];
    size_t tableSize = ELEMENT(metadataNames);
    size_t blanks, tokenSize;
    const char *token;
    const char *cleanToken;
    const char delim = ',';
    int32_t* storeBuf = (int32_t*)metadataCache;
    std::vector<std::string> tokens;
    getTokens(src, delim, tokens);

    for (size_t i = 0; i < tokens.size(); i++) {
        token = tokens.at(i).c_str();
        /* ignore any spaces in front of the string */
        blanks = strspn(token," ");
        cleanToken = token + blanks;
        /**
         * Parse the token without blanks.
         * TODO: Add support for simple wildcard to allow things like
         * android.request.*
         */
        tokenSize = STRLEN_S(cleanToken);
        for (unsigned int i = 0; i< tableSize; i++) {
            if (strncmp(cleanToken, metadataNames[i].name, tokenSize) == 0) {
                storeBuf[count] = metadataNames[i].value;
                count++;
            }
        }
        if (count >= maxCount) {
            LOGW("Too many keys found (%d)- ignoring the rest", count);
            /* if this happens then we should increase the size of the
             * mMetadataCache
             */
            break;
        }
    }
    return count;
}

/**
 * Parses the string with the avaialble input-output formats map
 * a format map is made of 3 elements
 * - Input Format
 * - Number output formats it can be converted in to
 * - List of the output formats.
 * we parse the string in 3 steps
 * example of valid input-output formats map is:
 * RAW_OPAQUE,3,BLOB,IMPLEMENTATION_DEFINED,YCbCr_420_888
 *
 * \param src: string to be parsed
 * \param tagInfo: descriptor of the static metadata. this is the entry from the
 * table defined in the autogenerated code
 * \param metadataCacheSize:the upper limit size of the dest buffer
 * \param metadataCache: the dest buffer to store the medatada after persed
 *
 * \return number of int32 entries to be stored
 */
int CameraProfiles::parseAvailableInputOutputFormatsMap(const char *src,
        const metadata_tag_t *tagInfo,
        std::vector<MetaValueRefTable> refTables,
        int metadataCacheSize,
        int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);

    int count = 0;  // entry count
    int maxCount = metadataCacheSize/camera_metadata_type_size[tagInfo->type];
    int ret;
    char * endPtr = nullptr;
    int parseStep = 1;
    int32_t *i32;
    int numOutputFormats = 0;

    const metadata_value_t * activeTable;
    int activeTableLen = 0;

    void *storeBuf = metadataCache;
    void *next;

    if (refTables.size() < 1) {
        LOGE("incomplete reference table :%zu", refTables.size());
        return count;
    }

    do {
        endPtr = (char *) strchr(src, ',');
        if (endPtr)
            *endPtr = 0;

        if (parseStep == 1) {  // Step 1 parse the input format
            if (STRLEN_S(src) == 0) break;
            // detect empty string. It means we are done, so get out of the loop
            activeTable = refTables[0].table;
            activeTableLen = refTables[0].tableSize;
            ret = convertEnum(storeBuf, src, tagInfo->type, activeTable,
                              activeTableLen, &next);
            if (ret == 1) {
                count++;
                storeBuf = next;
            } else {
                LOGE("Malformed enum in format map %s", src);
                break;
            }
        } else if (parseStep == 2) {  // Step 2: Parse the num of output formats
            i32 = reinterpret_cast<int32_t*>(storeBuf);
            i32[0] = strtol(src, &endPtr, 10);
            numOutputFormats = i32[0];
            count += 1;
            storeBuf = reinterpret_cast<void*>(&i32[1]);
            LOGD("Num of output formats = %d", i32[0]);

        } else {  // Step3 parse the output formats
            activeTable = refTables[0].table;
            activeTableLen =  refTables[0].tableSize;
            for (int i = 0; i < numOutputFormats; i++) {
                ret = convertEnum(storeBuf, src, tagInfo->type, activeTable,
                                  activeTableLen, &next);
                if (ret == 1) {
                    count += 1;
                    if (endPtr == nullptr) return count;
                    src = endPtr + 1;
                    storeBuf = next;
                } else {
                    LOGE("Malformed enum in format map %s", src);
                    break;
                }
                if (i < numOutputFormats - 1) {
                    endPtr = (char *) strchr(src, ',');
                    if (endPtr)
                        *endPtr = 0;
                }
            }
        }

        if (endPtr) {
            src = endPtr + 1;
            src = skipWhiteSpace(src);
            parseStep++;
            /* parsing steps go from 1 to 3 */
            if (parseStep == 4) {
                parseStep = 1;
            }
        }
    } while (count < maxCount && endPtr);

    if (endPtr != nullptr) {
        LOGW("Formats Map string too long for parser");
    }

    return count;
}


int CameraProfiles::parseSizes(const char *src,
                               const metadata_tag_t *tagInfo,
                               int metadataCacheSize,
                               int64_t* metadataCache)
{
    HAL_TRACE_CALL(1);
    int entriesFound = 0;

    entriesFound = parseData(src, tagInfo, metadataCacheSize, metadataCache);

    if (entriesFound % 2) {
        LOGE("Odd number of entries (%d), resolutions should have an even "
              "number of entries", entriesFound);
        entriesFound -= 1; //make it even Ignore the last one
    }
    return entriesFound;
}

int CameraProfiles::parseImageFormats(const char *src,
                                      const metadata_tag_t *tagInfo,
                                      int metadataCacheSize,
                                      int64_t *metadataCache)
{
    /**
     * DEPRECATED in V 3.2: TODO: add warning and extra checks
     */
    HAL_TRACE_CALL(1);
    int entriesFound = 0;

    entriesFound = parseEnum(src, tagInfo, metadataCacheSize, metadataCache);

    return entriesFound;
}

int CameraProfiles::parseRectangle(const char *src,
                                   const metadata_tag_t *tagInfo,
                                   int metadataCacheSize,
                                   int64_t *metadataCache)
{
    HAL_TRACE_CALL(1);
    int entriesFound = 0;
    entriesFound = parseData(src, tagInfo, metadataCacheSize, metadataCache);

    if (entriesFound % 4) {
        LOGE("incorrect number of entries (%d), rectangles have 4 values",
                    entriesFound);
        entriesFound -= entriesFound % 4; //round to multiple of 4
    }

    return entriesFound;
}
int CameraProfiles::parseBlackLevelPattern(const char *src,
                                           const metadata_tag_t *tagInfo,
                                           int metadataCacheSize,
                                           int64_t *metadataCache)
{
    HAL_TRACE_CALL(1);
    int entriesFound = 0;
    entriesFound = parseData(src, tagInfo, metadataCacheSize, metadataCache);
    if (entriesFound % 4) {
        LOGE("incorrect number of entries (%d), black level pattern have 4 values",
                    entriesFound);
        entriesFound -= entriesFound % 4; //round to multiple of 4
    }
    return entriesFound;
}

int CameraProfiles::parseStreamConfigDuration(const char *src,
        const metadata_tag_t *tagInfo,
        std::vector<MetaValueRefTable> refTables,
        int metadataCacheSize,
        int64_t *metadataCache)
{
    HAL_TRACE_CALL(1);
    int count = 0;  // entry count
    int maxCount = metadataCacheSize/camera_metadata_type_size[tagInfo->type];
    int ret;
    char * endPtr = nullptr;
    int parseStep = 1;
    int64_t *i64;

    const metadata_value_t * activeTable;
    int activeTableLen = 0;

    void *storeBuf = metadataCache;
    void *next;

    if (refTables.size() < 1) {
        LOGE("incomplete reference table :%zu", refTables.size());
        return count;
    }

    do {
        endPtr = (char *) strchr(src, ',');
        if (endPtr)
            *endPtr = 0;

        if (parseStep == 1) {  // Step 1 parse the format
            if (STRLEN_S(src) == 0) break;
            // detect empty string. It means we are done, so get out of the loop
            activeTable = refTables[0].table;
            activeTableLen = refTables[0].tableSize;
            ret = convertEnum(storeBuf, src, tagInfo->type, activeTable,
                              activeTableLen, &next);
            if (ret == 1) {
                count++;
                storeBuf = next;
            } else {
                LOGE("Malformed enum in stream configuration duration %s", src);
                break;
            }

        } else if (parseStep == 2) {  // Step 2: Parse the resolution
            i64 = reinterpret_cast<int64_t*>(storeBuf);
            i64[0] = strtol(src, &endPtr, 10);
            if (endPtr == nullptr || *endPtr != 'x') {
                LOGE("Malformed resolution in stream duration configuration");
                break;
            }
            src = endPtr + 1;
            i64[1] = strtol(src, &endPtr, 10);
            storeBuf = reinterpret_cast<void*>(&i64[2]);
            count += 2;
            LOG1("  - %" PRId64 "x%" PRId64 " -", i64[0], i64[1]);

        } else {  // Step3 parse the duration

            i64 = reinterpret_cast<int64_t*>(storeBuf);
            if (endPtr)
                i64[0] = strtol(src, &endPtr, 10);
            else
                i64[0] = strtol(src, nullptr, 10); // Do not update endPtr
            storeBuf = reinterpret_cast<void*>(&i64[1]);
            count += 1;
            LOG1("  - %" PRId64 " ns -", i64[0]);
        }

        if (endPtr) {
            src = endPtr + 1;
            src = skipWhiteSpace(src);
            parseStep++;
            /* parsing steps go from 1 to 3 */
            if (parseStep == 4) {
                parseStep = 1;
                LOG1("Stream Configuration Duration found");
            }
        }
    } while (count < maxCount && endPtr);

    if (endPtr != nullptr) {
        LOGW("Stream configuration duration string too long for parser");
    }
    /**
     * Total number of entries per stream configuration is 4
     * - one for the format
     * - two for the resolution
     * - one for the duration
     * The total entry count should be multiple of 4
     */
    if (count % 4) {
        LOGE("Malformed string for stream config duration."
                " ignoring last %d entries", count % 4);
        count -= count % 4;
    }
    return count;
}
/**
 *
 * Checks whether the sensor named in a profile is present in the list of
 * runtime detected sensors.
 * The result of this method helps to decide whether to use a particular profile
 * from the XML file.
 *
 * \param[in] detectedSensors vector with the description of the runtime
 *                            detected sensors.
 * \param[in] profileName name of the sensor present in the XML config file.
 * \param[in] cameraId camera Id for the sensor name in the XML.
 *
 * \return true if the sensor named in the profile is available in HW.
 */
bool CameraProfiles::isSensorPresent(std::vector<SensorDriverDescriptor> &detectedSensors,
                                     const char *profileName, int cameraId) const
{
    for (unsigned int i = 0; i < detectedSensors.size(); i++) {
        /*
         * Logic for legacy platforms with only 1-2 sensors.
         */
        if ((detectedSensors[i].mIspPort == PRIMARY && cameraId == 0) ||
            (detectedSensors[i].mIspPort == SECONDARY && cameraId == 1) ||
            (detectedSensors[i].mIspPort == UNKNOWN_PORT)) {
            if (detectedSensors[i].mSensorName == profileName) {
                LOG1("@%s: mUseEntry is true, mSensorIndex = %d, name = %s",
                        __FUNCTION__, cameraId, profileName);
                return true;
            }
        }
        /*
         * Logic for new platforms that support more than 2 sensors.
         * To uniquely match an XML profile to a sensor present in HW we will
         * use 2 pieces of information:
         * - sensor name
         * - CSI port
         * Current implementation only uses sensor name. CSI port is needed in
         * cases where we have same sensor name in different ports.
         * TODO add this to XML part
         */
        if (detectedSensors[i].mSensorDevType == SENSOR_DEVICE_MC) {
           if (detectedSensors[i].mSensorName == profileName) {
               LOG1("@%s: mUseEntry is true, mSensorIndex = %d, name = %s",
                       __FUNCTION__, cameraId, profileName);
               return true;
           }
       }
    }

    return false;
}
/**
 * This function will check which field that the parser parses to.
 *
 * The field is set to 5 types.
 * FIELD_INVALID FIELD_SENSOR_COMMON FIELD_SENSOR_ANDROID_METADATA FIELD_SENSOR_VENDOR_METADATA and FIELD_COMMON
 *
 * \param name: the element's name.
 * \param atts: the element's attribute.
 */
void CameraProfiles::checkField(CameraProfiles *profiles,
                                const char *name,
                                const char **atts)
{
    if (!strcmp(name, "Profiles")) {
        mXmlSensorIndex = atoi(atts[1]);
        if (mXmlSensorIndex > MAX_CAMERAS) {
            LOGE("ERROR: bad camera id %d!", mSensorIndex);
            return;
        }

        profiles->mUseEntry = false;
        int attIndex = 2;
        if (atts[attIndex]) {
            if (strcmp(atts[attIndex], "name") == 0) {
                mSensorIndex++;
                LOG1("@%s: mSensorIndex = %d, name = %s, mSensorNames.size():%zu",
                        __FUNCTION__, mSensorIndex,
                        atts[attIndex + 1], profiles->mSensorNames.size());

                profiles->mUseEntry = isSensorPresent(profiles->mSensorNames,
                                                      atts[attIndex + 1],
                                                      mSensorIndex);

                if (profiles->mUseEntry) {
                    mCameraIdToSensorName.insert(make_pair(mSensorIndex, std::string(atts[attIndex + 1])));
                }
            } else {
                LOGE("unknown attribute atts[%d] = %s", attIndex, atts[attIndex]);
            }
        } else {
            // for platforms that don't have the name field in the camera profiles.
            profiles->mUseEntry = true;
            mSensorIndex++;
        }

        if (profiles->mUseEntry
                && mSensorIndex >= mStaticMeta.size()
                && mStaticMeta.size() < profiles->mSensorNames.size())
            addCamera(mSensorIndex);
    } else if (strcmp(name, "Supported_hardware") == 0) {
        mCurrentDataField = FIELD_SUPPORTED_HARDWARE;
        mItemsCount = -1;
    } else if (strcmp(name, "Android_metadata") == 0) {
        mCurrentDataField = FIELD_ANDROID_STATIC_METADATA;
        mItemsCount = -1;
    } else if (strcmp(name, "Common") == 0) {
        mCurrentDataField = FIELD_COMMON;
        mItemsCount = -1;
    }

    LOG1("@%s: name:%s, field %d", __FUNCTION__, name, mCurrentDataField);
    return;
}

void CameraProfiles::handleSupportedHardware(const char *name, const char **atts)
{
    LOG1("@%s, type:%s", __FUNCTION__, name);
    if (strcmp(atts[0], "value") != 0) {
        LOGE("name:%s, atts[0]:%s, xml format wrong", name, atts[0]);
        return;
    }

    if (strcmp(name, "hwType") == 0) {
        CameraInfo *info = nullptr;
        mCameraInfoPool.acquireItem(&info);
        if (info != nullptr) {
            info->parser = nullptr;
            info->hwType = atts[1];
            info->xmlCameraId = mXmlSensorIndex;
            mCameraIdToCameraInfo.insert(std::make_pair(mSensorIndex, info));
            LOG2("Add sensor: %s to mCameraIdToCameraInfo with key: %d", name, mSensorIndex);
        } else {
            LOGE("Failed to get camera info for sensor index %d", mSensorIndex);
        }
    } else {
        LOGE("Unhandled xml attribute in Supported_hardware");
    }
}

/**
 * This function will handle all the common related elements.
 *
 * It will be called in the function startElement
 *
 * \param name: the element's name.
 * \param atts: the element's attribute.
 */
void CameraProfiles::handleCommon(const char *name, const char **atts)
{
    LOG1("@%s, name:%s, atts[0]:%s", __FUNCTION__, name, atts[0]);

    if (strcmp(atts[0], "value") != 0) {
        LOGE("name:%s, atts[0]:%s, xml format wrong", name, atts[0]);
        return;
    }
}

bool CameraProfiles::validateStaticMetadata(const char *name, const char **atts)
{
    /**
     * string validation
     */
    size_t nameSize = strnlen(name, MAX_METADATA_NAME_LENTGTH);
    size_t attrNameSize = strnlen(atts[0], MAX_METADATA_ATTRIBUTE_NAME_LENTGTH);
    size_t attrValueSize = strnlen(atts[1], MAX_METADATA_ATTRIBUTE_VALUE_LENTGTH);
    if ((attrValueSize == MAX_METADATA_ATTRIBUTE_VALUE_LENTGTH) ||
        (attrNameSize == MAX_METADATA_ATTRIBUTE_NAME_LENTGTH) ||
        (nameSize == MAX_METADATA_NAME_LENTGTH)) {
        LOGW("Warning XML strings too long ignoring this tag %s", name);
        return false;
    }

    if ((strncmp(atts[0], "value", attrNameSize) != 0) ||
            (attrValueSize == 0)) {
        LOGE("Check atts failed! name: %s, atts[0]: \"%s\", atts[1]: \"%s\", the format of xml is wrong!", name, atts[0], atts[1]);
        return false;
    }

    return true;
}

const metadata_tag_t *CameraProfiles::findTagInfo(const char *name,
                                                  const metadata_tag_t *tagsTable,
                                                  unsigned int size)
{
    size_t nameSize = strnlen(name, MAX_METADATA_NAME_LENTGTH);
    unsigned int index = 0;
    const metadata_tag_t *tagInfo = nullptr;

    for (index = 0; index < size; index++) {
        if (!strncmp(name, tagsTable[index].name, nameSize)) {
            tagInfo = &tagsTable[index];
            break;
        }
    }
    if (index >= size) {
        LOGW("Parser does not support tag %s! - ignoring", name);
    }

    return tagInfo;
}

int CameraProfiles::parseGenericTypes(const char *src,
                                      const metadata_tag_t *tagInfo,
                                      int metadataCacheSize,
                                      int64_t *metadataCache)
{
    int count = 0;
    switch (tagInfo->arrayTypedef) {
            case BOOLEAN:
            case ENUM_LIST:
                count = parseEnum(src, tagInfo, metadataCacheSize, metadataCache);
                break;
            case RANGE_INT:
            case RANGE_LONG:
                count = parseData(src, tagInfo, metadataCacheSize, metadataCache);
                break;
            case SIZE_F:
            case SIZE:
                count = parseSizes(src, tagInfo, metadataCacheSize, metadataCache);
                break;
            case RECTANGLE:
                count = parseRectangle(src, tagInfo, metadataCacheSize, metadataCache);
                break;
            case IMAGE_FORMAT:
                count = parseImageFormats(src, tagInfo, metadataCacheSize, metadataCache);
                break;
            case BLACK_LEVEL_PATTERN:
                count = parseBlackLevelPattern(src, tagInfo, metadataCacheSize, metadataCache);
                break;
            case TYPEDEF_NONE: /* Single values*/
                if (tagInfo->enumTable) {
                    count = parseEnum(src, tagInfo, metadataCacheSize, metadataCache);
                } else {
                    count = parseData(src, tagInfo, metadataCacheSize, metadataCache);
                }
                break;
            default:
                LOGW("Unsupported typedef %s", tagInfo->name);
                break;
            }

    return count;
}

/**
 * the callback function of the libexpat for handling of one element start
 *
 * When it comes to the start of one element. This function will be called.
 *
 * \param userData: the pointer we set by the function XML_SetUserData.
 * \param name: the element's name.
 */
void CameraProfiles::startElement(void *userData, const char *name, const char **atts)
{
    CameraProfiles *profiles = (CameraProfiles *)userData;

    if (profiles->mCurrentDataField == FIELD_INVALID) {
        profiles->checkField(profiles, name, atts);
        return;
    }
    LOG2("@%s: name:%s, for sensor %d", __FUNCTION__, name, profiles->mSensorIndex);

    profiles->mItemsCount++;

    switch (profiles->mCurrentDataField) {
        case FIELD_SUPPORTED_HARDWARE:
            if (profiles->mUseEntry)
                profiles->handleSupportedHardware(name, atts);
            break;
        case FIELD_ANDROID_STATIC_METADATA:
            if (profiles->mUseEntry)
                profiles->handleAndroidStaticMetadata(name, atts);

            break;
        case FIELD_COMMON:
            if (profiles->mStaticMeta.size() > 0)
                profiles->handleCommon(name, atts);

            break;
        default:
            LOGE("line:%d, go to default handling", __LINE__);
            break;
    }
}

/**
 * the callback function of the libexpat for handling of one element end
 *
 * When it comes to the end of one element. This function will be called.
 *
 * \param userData: the pointer we set by the function XML_SetUserData.
 * \param name: the element's name.
 */
void CameraProfiles::endElement(void *userData, const char *name)
{
    CameraProfiles *profiles = (CameraProfiles *)userData;
    if (!strcmp(name, "Profiles")) {
        profiles->mCurrentDataField = FIELD_INVALID;
        if (profiles->mUseEntry)
            profiles->mProfileEnd[profiles->mSensorIndex] = true;
    } else if (!strcmp(name, "Supported_hardware")
             || !strcmp(name, "Android_metadata")
             || !strcmp(name, "Common")) {
        profiles->mCurrentDataField = FIELD_INVALID;
        profiles->mItemsCount = -1;
    }
    return;
}

/**
 * Get camera configuration from xml file
 *
 * The function will read the xml configuration file firstly.
 * Then it will parse out the camera settings.
 * The camera setting is stored inside this CameraProfiles class.
 *
 */
void CameraProfiles::getDataFromXmlFile(void)
{
    int done;
    void *pBuf = nullptr;
    FILE *fp = nullptr;
    LOG1("@%s", __FUNCTION__);
    camera_metadata_t *currentMeta = nullptr;
    status_t res;
    int tag = ANDROID_REQUEST_AVAILABLE_CHARACTERISTICS_KEYS;

    fp = ::fopen(mXmlConfigName.c_str(), "r");
    if (nullptr == fp) {
        LOGE("line:%d, fp is nullptr", __LINE__);
        return;
    }

    XML_Parser parser = ::XML_ParserCreate(nullptr);
    if (nullptr == parser) {
        LOGE("line:%d, parser is nullptr", __LINE__);
        goto exit;
    }
    ::XML_SetUserData(parser, this);
    ::XML_SetElementHandler(parser, startElement, endElement);

    pBuf = ::operator new(BUFFERSIZE);
    mMetadataCache = new int64_t[METADATASIZE];

    do {
        int len = (int)::fread(pBuf, 1, BUFFERSIZE, fp);
        if (!len) {
            if (ferror(fp)) {
                clearerr(fp);
                goto exit;
            }
        }
        done = len < BUFFERSIZE;
        if (XML_Parse(parser, (const char *)pBuf, len, done) == XML_STATUS_ERROR) {
            LOGE("line:%d, XML_Parse error", __LINE__);
            goto exit;
        }
    } while (!done);

    if (mStaticMeta.size() > 0) {
        for (unsigned int i = 0; i < mStaticMeta.size(); i++) {
            currentMeta = mStaticMeta.at(i);
            if (currentMeta == nullptr) {
                LOGE("can't get the static metadata");
                goto exit;
            }
            // update REQUEST_AVAILABLE_CHARACTERISTICS_KEYS
            int *keys = mCharacteristicsKeys[i].data();
            res = MetadataHelper::updateMetadata(currentMeta, tag, keys, mCharacteristicsKeys[i].size());
            if (res != OK)
                LOGE("call add/update_camera_metadata_entry fail for request.availableCharacteristicsKeys");
        }
    }
exit:
    if (parser)
        ::XML_ParserFree(parser);

    ::operator delete(pBuf);

    if (mMetadataCache) {
        delete [] mMetadataCache;
        mMetadataCache = nullptr;
    }
    if (fp)
        ::fclose(fp);
}

CameraHwType CameraProfiles::getCameraHwforId(int cameraId)
{
    LOG2("@%s cameraId: %d", __FUNCTION__, cameraId);

    std::map<int, CameraInfo*>::iterator it =
                            mCameraIdToCameraInfo.find(cameraId);
    if (it == mCameraIdToCameraInfo.end()) {
        LOGE("Camera id not found, BUG, this should not happen!!mSensorIndex = %d", cameraId);
        return SUPPORTED_HW_UNKNOWN;
    }

    CameraInfo *info = it->second;
    std::string hwType = info->hwType;

    if (hwType == "SUPPORTED_HW_RKISP1") {
        return SUPPORTED_HW_RKISP1;
    } else
        LOGE("ERROR: Camera HW type wrong in xml");
        return SUPPORTED_HW_UNKNOWN;
}

void CameraProfiles::dumpSupportedHWSection(int cameraId) {
    LOGD("@%s", __FUNCTION__);
    std::map<int, CameraInfo*>::iterator it =
                            mCameraIdToCameraInfo.find(cameraId);
    if (it == mCameraIdToCameraInfo.end()) {
        LOGE("Camera id not found, BUG, this should not happen!!mSensorIndex = %d", cameraId);
        return;
    }

    CameraInfo *info = it->second;
    LOGD("element name hwType element value = %s", info->hwType.c_str());
}

void CameraProfiles::dumpStaticMetadataSection(int cameraId)
{
    LOGD("@%s", __FUNCTION__);
    if (mStaticMeta.size() > 0)
        MetadataHelper::dumpMetadata(mStaticMeta[cameraId]);
    else {
        LOGE("Camera isn't added, unable to get the static metadata");
    }
}

void CameraProfiles::dumpCommonSection()
{
    LOGD("@%s", __FUNCTION__);
    LOGD("element name: boardName, element value = %s", mCameraCommon->mBoardName.c_str());
    LOGD("element name: productName, element value = %s", mCameraCommon->productName());
    LOGD("element name: manufacturerName, element value = %s", mCameraCommon->manufacturerName());
    LOGD("element name: mSupportDualVideo, element value = %d", mCameraCommon-> mSupportDualVideo);
    LOGD("element name: supportExtendedMakernote, element value = %d", mCameraCommon->mSupportExtendedMakernote);
}

// To be modified when new elements or sections are added
// Use LOGD for traces to be visible
void CameraProfiles::dump()
{
    LOGD("===========================@%s======================", __FUNCTION__);
    for (unsigned int i = 0; i <= mSensorIndex; i++) {
        dumpSupportedHWSection(i);
        dumpStaticMetadataSection(i);
    }
    dumpCommonSection();
    LOGD("===========================end======================");
}

} NAMESPACE_DECLARATION_END
