/* INTEL CONFIDENTIAL
* Copyright (c) 2009 Intel Corporation.  All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
* Corporation or its suppliers or licensors.  Title to the
* Material remains with Intel Corporation or its suppliers and
* licensors.  The Material contains trade secrets and proprietary
* and confidential information of Intel or its suppliers and
* licensors. The Material is protected by worldwide copyright and
* trade secret laws and treaty provisions.  No part of the Material
* may be used, copied, reproduced, modified, published, uploaded,
* posted, transmitted, distributed, or disclosed in any way without
* Intel's prior express written permission.
*
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you
* by disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel or otherwise. Any license
* under such intellectual property rights must be express and
* approved by Intel in writing.
*
*/



#include "AsfDataParser.h"
#include "AsfGuids.h"
#include "AsfObjects.h"
#include <string.h>
#include <utils/Log.h>
#include "AsfHeaderParser.h"

AsfHeaderParser *AsfDataParser::mHeaderParser = NULL;

using namespace std;
// Helper fucctions

static inline uint8_t lengthType2Bytes(uint8_t lengthType) {
    // lengthType: 0    1   2   3
    // bits:            0    8  16  32
    // bytes:         0    1   2   4
    return 4 >> (3 - (lengthType & 0x03));
}

static inline uint32_t getModuleValue(uint32_t value, uint8_t lengthType) {
    switch (lengthType) {
        case 0:
            return 0; // field does not exist
        case 1:
            return value % 0x100; // (BYTE)
        case 2:
            return value % 0x10000;  // (WORD)
        case 3:
            return value; //(DWORD)
    }
    return value;
}

static inline uint32_t getFieldValue(uint8_t *buffer, uint8_t lengthType) {
    switch (lengthType) {
        case 0:
            return 0; // field does not exist
        case 1:
            return *buffer;
        case 2:
            return *(uint16_t*)buffer;
        case 3:
            return *(uint32_t*)buffer;
    }
    // This line should not be reached
    return 0xffffffff ;
 }

static void freePayloadDataInfo(AsfPayloadDataInfo *header) {
    while (header) {
        AsfPayloadDataInfo *next = header->next;
        delete header;
        header = next;
    }
}
AsfPayloadDataInfoPool::AsfPayloadDataInfoPool()
    : mFirstDataInfo(NULL),
      mLastDataInfo(NULL) {
}

AsfPayloadDataInfoPool::~AsfPayloadDataInfoPool() {
    freePayloadDataInfo(mFirstDataInfo);
}

void AsfPayloadDataInfoPool::releasePayloadDataInfo(AsfPayloadDataInfo *info) {
    if (info == NULL) {
        return;
    }

    if (mFirstDataInfo == NULL) {
        mFirstDataInfo = info;
    } else {
        mLastDataInfo->next = info;
    }
    while (info->next != NULL) {
        info = info->next;
    }
    mLastDataInfo = info;
}

AsfPayloadDataInfo* AsfPayloadDataInfoPool::getPayloadDataInfo() {
    AsfPayloadDataInfo *entry;

    if (mFirstDataInfo == NULL) {
        entry =  new AsfPayloadDataInfo;
        if (entry == NULL) {
            return NULL;
        }
    } else {
        entry = mFirstDataInfo;
        mFirstDataInfo = mFirstDataInfo->next;
        if (mFirstDataInfo == NULL) {
            mLastDataInfo = NULL;
        }
    }
    memset(entry, 0, sizeof(AsfPayloadDataInfo));
    return entry;
}


int AsfErrorCorrectionData::parse(uint8_t *buffer, uint32_t size) {
    errorCorrectionFlags.value = *buffer;

    blockSize = 0;
    if (errorCorrectionFlags.bits.errorCorrectionPresent == 0) {
        return ASF_PARSER_SUCCESS;
    }

    blockSize = 1;
    // determine if Error Correction Data Length is valid
    if (errorCorrectionFlags.bits.errorCorrectionLengthType == 0) {
        // Error Correction Data Length is valid only if the value of the Error Correction Length Type is 00

        // Error Correction Data Length should be 0010
        // Opaque Data Present should be set to 0
        blockSize += errorCorrectionFlags.bits.errorCorrectionDataLength;
        return ASF_PARSER_SUCCESS;
    }

    // if Error Correction Length Type is different thant 00, Error Correction Data Length shall be zero.
    if (errorCorrectionFlags.bits.errorCorrectionDataLength == 0) {
        return ASF_PARSER_SUCCESS;
    }

    return ASF_PARSER_BAD_VALUE;
}


int AsfPayloadParsingInformation::parse(uint8_t *buffer, uint32_t size) {
    lengthTypeFlags.value = *buffer;
    propertyFlags.value = *(buffer  + 1);

    // lengthTypeFlags:
    // sequence type should be set to 00
    // packet length type should be set to 00 when creating content
    // propertyFlags:
    // replicated data length type should be set to 01 (BYTE)
    // offset into media object shall be set to 11 (DWORD)
    // media object number length type shall be set to 01 (BYTE)
    // stream number length type shalll be set to 01 (BYTE)

    blockSize = 2;
    packetLength = getFieldValue(buffer + blockSize, lengthTypeFlags.bits.packetLengthType);
    blockSize += lengthType2Bytes(lengthTypeFlags.bits.packetLengthType);

    sequence = getFieldValue(buffer + blockSize, lengthTypeFlags.bits.sequenceType);
    blockSize += lengthType2Bytes(lengthTypeFlags.bits.sequenceType);

    paddingLength = getFieldValue(buffer + blockSize, lengthTypeFlags.bits.paddingLengthType);
    blockSize += lengthType2Bytes(lengthTypeFlags.bits.paddingLengthType);

    sendTime = *(uint32_t*)(buffer + blockSize);
    blockSize += 4;

    duration = *(uint16_t*)(buffer + blockSize);
    blockSize += 2;

    return ASF_PARSER_SUCCESS;
}


int AsfSinglePayloadUncompressed::parse(uint8_t *buffer, uint32_t size, AsfPayloadDataInfo **out) {
    // initialize output
    int retVal = 0;
    *out = NULL;
    streamNumber.value = *buffer;
    blockSize = 1;

    mediaObjectNumber = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.mediaObjectNumberLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.mediaObjectNumberLengthType);

    offsetIntoMediaObject = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);

    replicatedDataLength = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.replicatedDataLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.replicatedDataLengthType);

    if (replicatedDataLength == 1) {
        // compressed payload
        blockSize == 0;
        return ASF_PARSER_COMPRESSED_PAYLOAD;
    }

    if (replicatedDataLength == 0) {
        // TODO:
        return ASF_PARSER_UNEXPECTED_VALUE;
    }

    if (replicatedDataLength < 8) {
        return ASF_PARSER_BAD_VALUE;
    }

    AsfPayloadDataInfo *obj = pool->getPayloadDataInfo();
    if (obj == NULL) {
        return ASF_PARSER_NO_MEMORY;
    }

    ALOGD("replicatedDataLength = %d", replicatedDataLength);

    // point to replicated data into object's buffer. Yet to be interpreted.
    obj->replicatedDataLength = replicatedDataLength;
    obj->replicatedData = buffer + blockSize;

    // Replicated data, at least 8 bytes
    obj->mediaObjectLength = *(uint32_t*)(buffer + blockSize);
    obj->presentationTime = *(uint32_t*)(buffer + blockSize + 4);

    blockSize += replicatedDataLength;

    // defined for temporary use as arg for getPayloadExtensionSystems
    uint8_t streamnumber = streamNumber.bits.streamNumber;
    vector<PayloadExtensionSystem *> *extSystems;
    retVal = AsfDataParser::mHeaderParser->getPayloadExtensionSystems(streamnumber, &extSystems);
    if (retVal != ASF_PARSER_SUCCESS) {
        ALOGD("Error while parsing Payload Extension Systems");
    } else {
        ALOGD("Extension System count = %d", extSystems->size());
        // find IV in replicated data
        int rep_data_offset = 0;

        for (int i = 0; i < extSystems->size(); i++) {
            // ptr to ext system's data in replicated data buffer.
            if ((extSystems->at(i)->extensionSystemId) == ASF_Payload_Extension_System_Encryption_Sample_ID) {
                obj->sampleID = obj->replicatedData + 8 + rep_data_offset;
            }
            if (extSystems->at(i)->extensionDataSize == 0xFFFF) {
                uint16_t nSize = *((uint16_t*) (obj->replicatedData + 8 + rep_data_offset));
                rep_data_offset += (sizeof(uint16_t) + nSize);
            } else {
                rep_data_offset += extSystems->at(i)->extensionDataSize;
            }
        }
    }

    obj->payloadData = buffer + blockSize;

    // size = packet length - packet header length
    // payload size = size - payload header size (blockSize) - padding length
    obj->payloadSize = size - blockSize - ppi->paddingLength;
    if ((int)obj->payloadSize <= 0) {
        delete obj;
        return ASF_PARSER_BAD_VALUE;
    }
    obj->offsetIntoMediaObject = offsetIntoMediaObject;
    obj->streamNumber = streamNumber.bits.streamNumber;
    obj->mediaObjectNumber = mediaObjectNumber;
    obj->keyframe = streamNumber.bits.keyFrameBit;
    obj->next = NULL;

    // skip padding data
    blockSize += ppi->paddingLength;
    *out = obj;
    return ASF_PARSER_SUCCESS;
}


int AsfSinglePayloadCompressed::parse(uint8_t *buffer, uint32_t size, AsfPayloadDataInfo **out) {
    // initialize output
    *out = NULL;
    streamNumber.value = *buffer;
    blockSize = 1;

    mediaObjectNumber = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.mediaObjectNumberLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.mediaObjectNumberLengthType);

    // presentation time is coded using the value of Offset Into Media Object Length Type
    presentationTime= getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);

    // must be 1
    replicatedDataLength = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.replicatedDataLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.replicatedDataLengthType);

    presentationTimeDelta = *(buffer + blockSize);
    blockSize++;

    int payloadLenRemaining = size - blockSize - ppi->paddingLength;
    if (payloadLenRemaining <= 0) {
        return ASF_PARSER_BAD_VALUE;
    }

    uint32_t pts = presentationTime;
    uint32_t objNumber = mediaObjectNumber;

    uint8_t subPayloadDataLength;
    AsfPayloadDataInfo *first = NULL, *next = NULL, *last = NULL;

    while (payloadLenRemaining > 0) {
        subPayloadDataLength = *(buffer + blockSize);
        blockSize++;
        payloadLenRemaining -= 1;

        next = pool->getPayloadDataInfo();
        if (next == NULL) {
            freePayloadDataInfo(first);
            return ASF_PARSER_NO_MEMORY;
        }

        next->payloadData = buffer + blockSize;
        next->payloadSize = subPayloadDataLength;
        next->presentationTime = pts;
        next->offsetIntoMediaObject = 0;
        next->mediaObjectLength = subPayloadDataLength;
        next->streamNumber = streamNumber.bits.streamNumber;
        next->mediaObjectNumber = getModuleValue(objNumber, ppi->propertyFlags.bits.mediaObjectNumberLengthType);
        next->keyframe = streamNumber.bits.keyFrameBit;
        next->next = NULL;

        if (first == NULL) {
            first = next;
            last = next;
        } else {
            last->next = next;
            last = next;
        }

        pts += presentationTimeDelta;
        objNumber++;
        blockSize += subPayloadDataLength;
        payloadLenRemaining -= subPayloadDataLength;
    }

    if (payloadLenRemaining != 0) {
        // TODO:
        freePayloadDataInfo(first);
        return ASF_PARSER_BAD_VALUE;
    }

    // skip padding data
    blockSize += ppi->paddingLength;
    *out = first;
    return ASF_PARSER_SUCCESS;
}


int AsfMultiplePayloadsHeader::parse(uint8_t *buffer, uint32_t size) {
    payloadFlags.value = *buffer;
    blockSize = 1;

    // number of payloads must not be 0
    if (payloadFlags.bits.numberOfPayloads == 0) {
        return ASF_PARSER_BAD_VALUE;
    }

    // payload length type should be set to 10 (WORD)
    return ASF_PARSER_SUCCESS;
}


int AsfMultiplePayloadsUncompressed::parse(uint8_t *buffer, uint32_t size, AsfPayloadDataInfo **out) {
    // initialize output
    int retVal = 0;
    *out = NULL;
    streamNumber.value = *buffer;
    blockSize = 1;

    mediaObjectNumber = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.mediaObjectNumberLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.mediaObjectNumberLengthType);

    offsetIntoMediaObject = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);

    replicatedDataLength = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.replicatedDataLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.replicatedDataLengthType);

    if (replicatedDataLength == 1) {
        // compressed payload
        blockSize == 0;
        return ASF_PARSER_COMPRESSED_PAYLOAD;
    }

    if (replicatedDataLength == 0) {
        // TODO:
        return ASF_PARSER_UNEXPECTED_VALUE;
    }

    if (replicatedDataLength < 8) {
        return ASF_PARSER_BAD_VALUE;
    }

    AsfPayloadDataInfo *obj = pool->getPayloadDataInfo();
    if (obj == NULL) {
        return ASF_PARSER_NO_MEMORY;
    }

    ALOGD("replicatedDataLength = %d", replicatedDataLength);

    // point to replicated data into object's buffer. Yet to be interpreted.
    obj->replicatedDataLength = replicatedDataLength;
    obj->replicatedData = buffer + blockSize;

    // at least 8 bytes replicated data
    obj->mediaObjectLength = *(uint32_t *)(buffer + blockSize);
    obj->presentationTime = *(uint32_t *)(buffer + blockSize + 4);

    blockSize += replicatedDataLength;

    // defined for temporary use as arg for getPayloadExtensionSystems
    uint8_t streamnumber = streamNumber.bits.streamNumber;
    vector<PayloadExtensionSystem *> *extSystems;
    retVal = AsfDataParser::mHeaderParser->getPayloadExtensionSystems(streamnumber, &extSystems);
    if (retVal != ASF_PARSER_SUCCESS) {
        ALOGD("Error while parsing Payload Extension Systems");
    } else {
        // find IV in replicated data
        int rep_data_offset = 0;
        for (int i = 0; i < extSystems->size(); i++) {
            // ptr to ext system's data in replicated data buffer.
            if ((extSystems->at(i)->extensionSystemId) == ASF_Payload_Extension_System_Encryption_Sample_ID) {
                obj->sampleID = obj->replicatedData + 8 + rep_data_offset;
            }
            rep_data_offset = rep_data_offset + extSystems->at(i)->extensionDataSize;
        }
    }

    // payload length must not be 0
    payloadLength = getFieldValue(buffer + blockSize, mpHeader->payloadFlags.bits.payloadLengthType);
    blockSize += lengthType2Bytes(mpHeader->payloadFlags.bits.payloadLengthType);

    if (payloadLength == 0 || payloadLength + blockSize > size) {
        delete obj;
        return ASF_PARSER_BAD_VALUE;
    }

    obj->payloadData = buffer + blockSize;
    obj->payloadSize = payloadLength;

    obj->offsetIntoMediaObject = offsetIntoMediaObject;
    obj->streamNumber = streamNumber.bits.streamNumber;
    obj->mediaObjectNumber = mediaObjectNumber;
    obj->keyframe = streamNumber.bits.keyFrameBit;
    obj->next = NULL;

    // skip payload data
    blockSize += payloadLength;
    *out = obj;
    return ASF_PARSER_SUCCESS;
}


int AsfMultiplePayloadsCompressed::parse(uint8_t *buffer, uint32_t size, AsfPayloadDataInfo **out) {
    // initialize output
    *out = NULL;
    streamNumber.value = *buffer;
    blockSize = 1;

    mediaObjectNumber = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.mediaObjectNumberLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.mediaObjectNumberLengthType);

    // presentation time is coded using the value of Offset Into Media Object Length Type
    presentationTime= getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.offsetIntoMediaObjectLengthType);

    // must be 1
    replicatedDataLength = getFieldValue(buffer + blockSize, ppi->propertyFlags.bits.replicatedDataLengthType);
    blockSize += lengthType2Bytes(ppi->propertyFlags.bits.replicatedDataLengthType);

    presentationTimeDelta = *(buffer + blockSize);
    blockSize++;

    // payload length must not be 0
    payloadLength = getFieldValue(buffer + blockSize, mpHeader->payloadFlags.bits.payloadLengthType);
    blockSize += lengthType2Bytes(mpHeader->payloadFlags.bits.payloadLengthType);
    if (payloadLength == 0 || blockSize + payloadLength > size) {
        return ASF_PARSER_BAD_VALUE;
    }

    // safe to case from uint32_t to int.
    int payloadLenRemaining = (int)payloadLength;
    uint32_t pts = presentationTime;
    uint32_t objNumber = mediaObjectNumber;
    uint8_t subPayloadDataLength;
    AsfPayloadDataInfo *first = NULL, *next = NULL, *last = NULL;

    while (payloadLenRemaining > 0) {
        subPayloadDataLength = *(buffer + blockSize);
        blockSize++;
        payloadLenRemaining -= 1;

        next = pool->getPayloadDataInfo();
        if (next == NULL) {
            freePayloadDataInfo(first);
            return ASF_PARSER_NO_MEMORY;
        }

        next->payloadData = buffer + blockSize;
        next->payloadSize = subPayloadDataLength;
        next->presentationTime = pts;
        next->offsetIntoMediaObject = 0;
        next->mediaObjectLength = subPayloadDataLength;
        next->streamNumber = streamNumber.bits.streamNumber;
        next->mediaObjectNumber = getModuleValue(objNumber, ppi->propertyFlags.bits.mediaObjectNumberLengthType);
        next->keyframe = streamNumber.bits.keyFrameBit;
        next->next = NULL;

        if (first == NULL) {
            first = next;
            last = next;
        } else {
            last->next = next;
            last = next;
        }

        pts += presentationTimeDelta;
        objNumber++;
        blockSize += subPayloadDataLength;
        payloadLenRemaining -= subPayloadDataLength;
    }

    if (payloadLenRemaining < 0) {
        // TODO:
        freePayloadDataInfo(first);
        return ASF_PARSER_BAD_VALUE;
    }

    // blockSize stays as it is
    *out = first;
    return ASF_PARSER_SUCCESS;
}


AsfDataParser::AsfDataParser(AsfHeaderParser *hdrparser)
    : mTotalDataPackets(0) {
    mSPUncompressed.ppi = &mPPI;
    mSPCompressed.ppi = &mPPI;
    mMPHeader.ppi = &mPPI;
    mMPUncompressed.ppi = &mPPI;
    mMPCompressed.ppi = &mPPI;
    mMPUncompressed.mpHeader = &mMPHeader;
    mMPCompressed.mpHeader = &mMPHeader;

    mSPUncompressed.pool = &mPool;
    mSPCompressed.pool = &mPool;
    mMPUncompressed.pool = &mPool;
    mMPCompressed.pool = &mPool;
    if (hdrparser) {
        AsfDataParser::mHeaderParser = hdrparser;
    }
}


AsfDataParser::~AsfDataParser(void) {
}

int AsfDataParser::parseHeader(uint8_t *buffer, uint32_t size) {
    if (size < sizeof(AsfDataObject)) {
        return ASF_PARSER_BAD_DATA;
    }
    AsfDataObject *obj = (AsfDataObject*)buffer;
    mTotalDataPackets = obj->totalDataPackets;
    return ASF_PARSER_SUCCESS;
}

uint64_t AsfDataParser::getTotalDataPackets() {
    return mTotalDataPackets;
}

int AsfDataParser::parsePacket(uint8_t *buffer, uint32_t size, AsfPayloadDataInfo **out) {
    int status;
    AsfPayloadDataInfo *first = NULL;

    status = mECD.parse(buffer, size);
    if (status != ASF_PARSER_SUCCESS) {
        return status;
    }

    buffer += mECD.blockSize;
    size -= mECD.blockSize;
    status = mPPI.parse(buffer, size);
    if (status != ASF_PARSER_SUCCESS) {
        return status;
    }

    buffer += mPPI.blockSize;
    size -= mPPI.blockSize;

    if (mPPI.lengthTypeFlags.bits.multiplePayloadsPresent) {
        status = mMPHeader.parse(buffer, size);
        if (status != ASF_PARSER_SUCCESS) {
            return status;
        }
        buffer += mMPHeader.blockSize;
        size -= mMPHeader.blockSize;

        AsfPayloadDataInfo *last = NULL, *next = NULL;
        for (int i = 0; i < mMPHeader.payloadFlags.bits.numberOfPayloads; i++) {
            status = mMPUncompressed.parse(buffer, size, &next);

            if (status == ASF_PARSER_SUCCESS) {
                buffer += mMPUncompressed.blockSize;
                size -= mMPUncompressed.blockSize;
            } else if (status == ASF_PARSER_COMPRESSED_PAYLOAD) {
                status = mMPCompressed.parse(buffer, size, &next);
                if (status != ASF_PARSER_SUCCESS) {
                    break;
                }
                buffer += mMPCompressed.blockSize;
                size -= mMPCompressed.blockSize;
            }
            else {
                break;
            }

            if ((int)size < 0) {
                status = ASF_PARSER_BAD_VALUE;
                break;
            }
            // concatenate the payloads.
            if (first == NULL) {
                first = next;
                last = next;
            }
            else {
                while (last->next != NULL) {
                    last = last->next;
                }
                last->next = next;
                last = next;
            }
        }
    }
    else {
        status = mSPUncompressed.parse(buffer, size, &first);

         if (status == ASF_PARSER_COMPRESSED_PAYLOAD) {
            status = mSPCompressed.parse(buffer, size, &first);
        }
    }

    if (status != ASF_PARSER_SUCCESS) {
        freePayloadDataInfo(first);
        return status;
    }

    *out = first;
    return ASF_PARSER_SUCCESS;
}

void AsfDataParser::releasePayloadDataInfo(AsfPayloadDataInfo *info) {
    mPool.releasePayloadDataInfo(info);
}
