/*
 * Copyright (C) 2017 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.
 */
#define LOG_TAG "libprotoutil"

#include <cinttypes>
#include <type_traits>

#include <android-base/file.h>
#include <android/util/protobuf.h>
#include <android/util/ProtoOutputStream.h>
#include <cutils/log.h>

namespace android {
namespace util {

ProtoOutputStream::ProtoOutputStream()
        :mBuffer(),
         mCopyBegin(0),
         mCompact(false),
         mDepth(0),
         mObjectId(0),
         mExpectedObjectToken(UINT64_C(-1))
{
}

ProtoOutputStream::~ProtoOutputStream()
{
}


void
ProtoOutputStream::clear()
{
    mBuffer.clear();
    mCopyBegin = 0;
    mCompact = false;
    mDepth = 0;
    mObjectId = 0;
    mExpectedObjectToken = UINT64_C(-1);
}

template<typename T>
bool
ProtoOutputStream::internalWrite(uint64_t fieldId, T val, const char* typeName)
{
    if (mCompact) return false;
    const uint32_t id = (uint32_t)fieldId;
    switch (fieldId & FIELD_TYPE_MASK) {
        case FIELD_TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
        case FIELD_TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
        case FIELD_TYPE_INT64:    writeInt64Impl(id, (int64_t)val);           break;
        case FIELD_TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int32_t)val);           break;
        case FIELD_TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
        case FIELD_TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
        case FIELD_TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int32_t)val);        break;
        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (int64_t)val);        break;
        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int32_t)val);     break;
        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (int64_t)val);     break;
        case FIELD_TYPE_ENUM:
            if (std::is_integral<T>::value) {
                writeEnumImpl(id, (int)val);
            } else {
                goto unsupported;
            }
            break;
        case FIELD_TYPE_BOOL:
            if (std::is_integral<T>::value) {
                writeBoolImpl(id, val != 0);
            } else {
                goto unsupported;
            }
            break;
        default:
            goto unsupported;
    }
    return true;

unsupported:
    ALOGW("Field type %" PRIu64 " is not supported when writing %s val.",
            (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT, typeName);
    return false;
}

bool
ProtoOutputStream::write(uint64_t fieldId, double val)
{
    return internalWrite(fieldId, val, "double");
}


bool
ProtoOutputStream::write(uint64_t fieldId, float val)
{
    return internalWrite(fieldId, val, "float");
}

bool
ProtoOutputStream::write(uint64_t fieldId, int val)
{
    return internalWrite(fieldId, val, "int");
}

bool
ProtoOutputStream::write(uint64_t fieldId, long val)
{
    if (mCompact) return false;
    const uint32_t id = (uint32_t)fieldId;
    switch (fieldId & FIELD_TYPE_MASK) {
        case FIELD_TYPE_DOUBLE:   writeDoubleImpl(id, (double)val);           break;
        case FIELD_TYPE_FLOAT:    writeFloatImpl(id, (float)val);             break;
        case FIELD_TYPE_INT64:    writeInt64Impl(id, (long long)val);         break;
        case FIELD_TYPE_UINT64:   writeUint64Impl(id, (uint64_t)val);         break;
        case FIELD_TYPE_INT32:    writeInt32Impl(id, (int)val);               break;
        case FIELD_TYPE_FIXED64:  writeFixed64Impl(id, (uint64_t)val);        break;
        case FIELD_TYPE_FIXED32:  writeFixed32Impl(id, (uint32_t)val);        break;
        case FIELD_TYPE_UINT32:   writeUint32Impl(id, (uint32_t)val);         break;
        case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val);            break;
        case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val);      break;
        case FIELD_TYPE_SINT32:   writeZigzagInt32Impl(id, (int)val);         break;
        case FIELD_TYPE_SINT64:   writeZigzagInt64Impl(id, (long long)val);   break;
        case FIELD_TYPE_ENUM:     writeEnumImpl(id, (int)val);                break;
        case FIELD_TYPE_BOOL:     writeBoolImpl(id, val != 0);                break;
        default:
            ALOGW("Field type %d is not supported when writing long val.",
                    (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
            return false;
    }
    return true;
}

bool
ProtoOutputStream::write(uint64_t fieldId, long long val)
{
    return internalWrite(fieldId, val, "long long");
}

bool
ProtoOutputStream::write(uint64_t fieldId, bool val)
{
    if (mCompact) return false;
    const uint32_t id = (uint32_t)fieldId;
    switch (fieldId & FIELD_TYPE_MASK) {
        case FIELD_TYPE_BOOL:
            writeBoolImpl(id, val);
            return true;
        default:
            ALOGW("Field type %" PRIu64 " is not supported when writing bool val.",
                    (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT);
            return false;
    }
}

bool
ProtoOutputStream::write(uint64_t fieldId, std::string val)
{
    if (mCompact) return false;
    const uint32_t id = (uint32_t)fieldId;
    switch (fieldId & FIELD_TYPE_MASK) {
        case FIELD_TYPE_STRING:
            writeUtf8StringImpl(id, val.c_str(), val.size());
            return true;
        default:
            ALOGW("Field type %" PRIu64 " is not supported when writing string val.",
                    (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT);
            return false;
    }
}

bool
ProtoOutputStream::write(uint64_t fieldId, const char* val, size_t size)
{
    if (mCompact) return false;
    const uint32_t id = (uint32_t)fieldId;
    switch (fieldId & FIELD_TYPE_MASK) {
        case FIELD_TYPE_STRING:
        case FIELD_TYPE_BYTES:
            writeUtf8StringImpl(id, val, size);
            return true;
        case FIELD_TYPE_MESSAGE:
            // can directly write valid format of message bytes into ProtoOutputStream without calling start/end
            writeMessageBytesImpl(id, val, size);
            return true;
        default:
            ALOGW("Field type %" PRIu64 " is not supported when writing char[] val.",
                    (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT);
            return false;
    }
}

/**
 * Make a token.
 *  Bits 61-63 - tag size (So we can go backwards later if the object had not data)
 *                - 3 bits, max value 7, max value needed 5
 *  Bit  60    - true if the object is repeated
 *  Bits 59-51 - depth (For error checking)
 *                - 9 bits, max value 511, when checking, value is masked (if we really
 *                  are more than 511 levels deep)
 *  Bits 32-50 - objectId (For error checking)
 *                - 19 bits, max value 524,287. that's a lot of objects. IDs will wrap
 *                  because of the overflow, and only the tokens are compared.
 *  Bits  0-31 - offset of the first size field in the buffer.
 */
static uint64_t
makeToken(uint32_t tagSize, bool repeated, uint32_t depth, uint32_t objectId, size_t sizePos) {
    return ((UINT64_C(0x07) & (uint64_t)tagSize) << 61)
            | (repeated ? (UINT64_C(1) << 60) : 0)
            | (UINT64_C(0x01ff) & (uint64_t)depth) << 51
            | (UINT64_C(0x07ffff) & (uint64_t)objectId) << 32
            | (UINT64_C(0x0ffffffff) & (uint64_t)sizePos);
}

/**
 * Get the encoded tag size from the token.
 */
static uint32_t getTagSizeFromToken(uint64_t token) {
    return 0x7 & (token >> 61);
}

/**
 * Get the nesting depth of startObject calls from the token.
 */
static uint32_t getDepthFromToken(uint64_t token) {
    return 0x01ff & (token >> 51);
}

/**
 * Get the location of the childRawSize (the first 32 bit size field) in this object.
 */
static uint32_t getSizePosFromToken(uint64_t token) {
    return (uint32_t)token;
}

uint64_t
ProtoOutputStream::start(uint64_t fieldId)
{
    if ((fieldId & FIELD_TYPE_MASK) != FIELD_TYPE_MESSAGE) {
        ALOGE("Can't call start for non-message type field: 0x%" PRIx64, fieldId);
        return 0;
    }

    uint32_t id = (uint32_t)fieldId;
    size_t prevPos = mBuffer.wp()->pos();
    mBuffer.writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
    size_t sizePos = mBuffer.wp()->pos();

    mDepth++;
    mObjectId++;
    mBuffer.writeRawFixed64(mExpectedObjectToken); // push previous token into stack.

    mExpectedObjectToken = makeToken(sizePos - prevPos,
        (bool)(fieldId & FIELD_COUNT_REPEATED), mDepth, mObjectId, sizePos);
    return mExpectedObjectToken;
}

void
ProtoOutputStream::end(uint64_t token)
{
    if (token != mExpectedObjectToken) {
        ALOGE("Unexpected token: 0x%" PRIx64 ", should be 0x%" PRIx64, token, mExpectedObjectToken);
        mDepth = UINT32_C(-1); // make depth invalid
        return;
    }

    uint32_t depth = getDepthFromToken(token);
    if (depth != (mDepth & 0x01ff)) {
        ALOGE("Unexpected depth: %" PRIu32 ", should be %" PRIu32, depth, mDepth);
        mDepth = UINT32_C(-1); // make depth invalid
        return;
    }
    mDepth--;

    uint32_t sizePos = getSizePosFromToken(token);
    // number of bytes written in this start-end session.
    int childRawSize = mBuffer.wp()->pos() - sizePos - 8;

    // retrieve the old token from stack.
    mBuffer.ep()->rewind()->move(sizePos);
    mExpectedObjectToken = mBuffer.readRawFixed64();

    // If raw size is larger than 0, write the negative value here to indicate a compact is needed.
    if (childRawSize > 0) {
        mBuffer.editRawFixed32(sizePos, -childRawSize);
        mBuffer.editRawFixed32(sizePos+4, -1);
    } else {
        // reset wp which erase the header tag of the message when its size is 0.
        mBuffer.wp()->rewind()->move(sizePos - getTagSizeFromToken(token));
    }
}

size_t
ProtoOutputStream::bytesWritten()
{
    return mBuffer.size();
}

bool
ProtoOutputStream::compact() {
    if (mCompact) return true;
    if (mDepth != 0) {
        ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing or extra calls to end.", mDepth);
        return false;
    }
    // record the size of the original buffer.
    size_t rawBufferSize = mBuffer.size();
    if (rawBufferSize == 0) return true; // nothing to do if the buffer is empty;

    // reset edit pointer and recursively compute encoded size of messages.
    mBuffer.ep()->rewind();
    if (editEncodedSize(rawBufferSize) == 0) {
        ALOGE("Failed to editEncodedSize.");
        return false;
    }

    // reset both edit pointer and write pointer, and compact recursively.
    mBuffer.ep()->rewind();
    mBuffer.wp()->rewind();
    if (!compactSize(rawBufferSize)) {
        ALOGE("Failed to compactSize.");
        return false;
    }
    // copy the reset to the buffer.
    if (mCopyBegin < rawBufferSize) {
        mBuffer.copy(mCopyBegin, rawBufferSize - mCopyBegin);
    }

    // mark true means it is not legal to write to this ProtoOutputStream anymore
    mCompact = true;
    return true;
}

/**
 * First compaction pass.  Iterate through the data, and fill in the
 * nested object sizes so the next pass can compact them.
 */
size_t
ProtoOutputStream::editEncodedSize(size_t rawSize)
{
    size_t objectStart = mBuffer.ep()->pos();
    size_t objectEnd = objectStart + rawSize;
    size_t encodedSize = 0;
    int childRawSize, childEncodedSize;
    size_t childEncodedSizePos;

    while (mBuffer.ep()->pos() < objectEnd) {
        uint32_t tag = (uint32_t)mBuffer.readRawVarint();
        encodedSize += get_varint_size(tag);
        switch (read_wire_type(tag)) {
            case WIRE_TYPE_VARINT:
                do {
                    encodedSize++;
                } while ((mBuffer.readRawByte() & 0x80) != 0);
                break;
            case WIRE_TYPE_FIXED64:
                encodedSize += 8;
                mBuffer.ep()->move(8);
                break;
            case WIRE_TYPE_LENGTH_DELIMITED:
                childRawSize = (int)mBuffer.readRawFixed32();
                childEncodedSizePos = mBuffer.ep()->pos();
                childEncodedSize = (int)mBuffer.readRawFixed32();
                if (childRawSize >= 0 && childRawSize == childEncodedSize) {
                    mBuffer.ep()->move(childRawSize);
                } else if (childRawSize < 0 && childEncodedSize == -1){
                    childEncodedSize = editEncodedSize(-childRawSize);
                    mBuffer.editRawFixed32(childEncodedSizePos, childEncodedSize);
                } else {
                    ALOGE("Bad raw or encoded values: raw=%d, encoded=%d at %zu",
                            childRawSize, childEncodedSize, childEncodedSizePos);
                    return 0;
                }
                encodedSize += get_varint_size(childEncodedSize) + childEncodedSize;
                break;
            case WIRE_TYPE_FIXED32:
                encodedSize += 4;
                mBuffer.ep()->move(4);
                break;
            default:
                ALOGE("Unexpected wire type %d in editEncodedSize at [%zu, %zu]",
                        read_wire_type(tag), objectStart, objectEnd);
                return 0;
        }
    }
    return encodedSize;
}

/**
 * Second compaction pass.  Iterate through the data, and copy the data
 * forward in the buffer, converting the pairs of uint32s into a single
 * unsigned varint of the size.
 */
bool
ProtoOutputStream::compactSize(size_t rawSize)
{
    size_t objectStart = mBuffer.ep()->pos();
    size_t objectEnd = objectStart + rawSize;
    int childRawSize, childEncodedSize;

    while (mBuffer.ep()->pos() < objectEnd) {
        uint32_t tag = (uint32_t)mBuffer.readRawVarint();
        switch (read_wire_type(tag)) {
            case WIRE_TYPE_VARINT:
                while ((mBuffer.readRawByte() & 0x80) != 0) {}
                break;
            case WIRE_TYPE_FIXED64:
                mBuffer.ep()->move(8);
                break;
            case WIRE_TYPE_LENGTH_DELIMITED:
                mBuffer.copy(mCopyBegin, mBuffer.ep()->pos() - mCopyBegin);

                childRawSize = (int)mBuffer.readRawFixed32();
                childEncodedSize = (int)mBuffer.readRawFixed32();
                mCopyBegin = mBuffer.ep()->pos();

                // write encoded size to buffer.
                mBuffer.writeRawVarint32(childEncodedSize);
                if (childRawSize >= 0 && childRawSize == childEncodedSize) {
                    mBuffer.ep()->move(childEncodedSize);
                } else if (childRawSize < 0){
                    if (!compactSize(-childRawSize)) return false;
                } else {
                    ALOGE("Bad raw or encoded values: raw=%d, encoded=%d",
                            childRawSize, childEncodedSize);
                    return false;
                }
                break;
            case WIRE_TYPE_FIXED32:
                mBuffer.ep()->move(4);
                break;
            default:
                ALOGE("Unexpected wire type %d in compactSize at [%zu, %zu]",
                        read_wire_type(tag), objectStart, objectEnd);
                return false;
        }
    }
    return true;
}

size_t
ProtoOutputStream::size()
{
    if (!compact()) {
        ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
        return 0;
    }
    return mBuffer.size();
}

bool
ProtoOutputStream::flush(int fd)
{
    if (fd < 0) return false;
    if (!compact()) return false;

    EncodedBuffer::iterator it = mBuffer.begin();
    while (it.readBuffer() != NULL) {
        if (!android::base::WriteFully(fd, it.readBuffer(), it.currentToRead())) return false;
        it.rp()->move(it.currentToRead());
    }
    return true;
}

EncodedBuffer::iterator
ProtoOutputStream::data()
{
    if (!compact()) {
        ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
        mBuffer.clear();
    }
    return mBuffer.begin();
}

void
ProtoOutputStream::writeRawVarint(uint64_t varint)
{
    mBuffer.writeRawVarint64(varint);
}

void
ProtoOutputStream::writeLengthDelimitedHeader(uint32_t id, size_t size)
{
    mBuffer.writeHeader(id, WIRE_TYPE_LENGTH_DELIMITED);
    // reserves 64 bits for length delimited fields, if first field is negative, compact it.
    mBuffer.writeRawFixed32(size);
    mBuffer.writeRawFixed32(size);
}

void
ProtoOutputStream::writeRawByte(uint8_t byte)
{
    mBuffer.writeRawByte(byte);
}


// =========================================================================
// Private functions

/**
 * bit_cast
 */
template <class From, class To>
inline To bit_cast(From const &from) {
    To to;
    memcpy(&to, &from, sizeof(to));
    return to;
}

inline void
ProtoOutputStream::writeDoubleImpl(uint32_t id, double val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
    mBuffer.writeRawFixed64(bit_cast<double, uint64_t>(val));
}

inline void
ProtoOutputStream::writeFloatImpl(uint32_t id, float val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
    mBuffer.writeRawFixed32(bit_cast<float, uint32_t>(val));
}

inline void
ProtoOutputStream::writeInt64Impl(uint32_t id, int64_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint64(val);
}

inline void
ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint32(val);
}

inline void
ProtoOutputStream::writeUint64Impl(uint32_t id, uint64_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint64(val);
}

inline void
ProtoOutputStream::writeUint32Impl(uint32_t id, uint32_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint32(val);
}

inline void
ProtoOutputStream::writeFixed64Impl(uint32_t id, uint64_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
    mBuffer.writeRawFixed64(val);
}

inline void
ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
    mBuffer.writeRawFixed32(val);
}

inline void
ProtoOutputStream::writeSFixed64Impl(uint32_t id, int64_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_FIXED64);
    mBuffer.writeRawFixed64(val);
}

inline void
ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_FIXED32);
    mBuffer.writeRawFixed32(val);
}

inline void
ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, int64_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint64((val << 1) ^ (val >> 63));
}

inline void
ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint32((val << 1) ^ (val >> 31));
}

inline void
ProtoOutputStream::writeEnumImpl(uint32_t id, int val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint32((uint32_t) val);
}

inline void
ProtoOutputStream::writeBoolImpl(uint32_t id, bool val)
{
    mBuffer.writeHeader(id, WIRE_TYPE_VARINT);
    mBuffer.writeRawVarint32(val ? 1 : 0);
}

inline void
ProtoOutputStream::writeUtf8StringImpl(uint32_t id, const char* val, size_t size)
{
    if (val == NULL) return;
    writeLengthDelimitedHeader(id, size);
    for (size_t i=0; i<size; i++) {
        mBuffer.writeRawByte((uint8_t)val[i]);
    }
}

inline void
ProtoOutputStream::writeMessageBytesImpl(uint32_t id, const char* val, size_t size)
{
    if (val == NULL) return;
    writeLengthDelimitedHeader(id, size);
    for (size_t i=0; i<size; i++) {
        mBuffer.writeRawByte(val[i]);
    }
}

} // util
} // android

