/*
 * 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(): ProtoOutputStream(new EncodedBuffer())
{
}

ProtoOutputStream::ProtoOutputStream(sp<EncodedBuffer> buffer)
        :mBuffer(buffer),
         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;

    sp<ProtoReader> reader = mBuffer->read();
    while (reader->readBuffer() != NULL) {
        if (!android::base::WriteFully(fd, reader->readBuffer(), reader->currentToRead())) {
            return false;
        }
        reader->move(reader->currentToRead());
    }
    return true;
}

bool
ProtoOutputStream::serializeToString(std::string* out)
{
    if (out == nullptr) return false;
    if (!compact()) return false;

    sp<ProtoReader> reader = mBuffer->read();
    out->reserve(reader->size());
    while (reader->hasNext()) {
        out->append(static_cast<const char*>(static_cast<const void*>(reader->readBuffer())),
                    reader->currentToRead());
        reader->move(reader->currentToRead());
    }
    return true;
}

bool
ProtoOutputStream::serializeToVector(std::vector<uint8_t>* out)
{
    if (out == nullptr) return false;
    if (!compact()) return false;

    sp<ProtoReader> reader = mBuffer->read();
    out->reserve(reader->size());
    while (reader->hasNext()) {
        const uint8_t* buf = reader->readBuffer();
        size_t size = reader->currentToRead();
        out->insert(out->end(), buf, buf + size);
        reader->move(size);
    }
    return true;
}

sp<ProtoReader>
ProtoOutputStream::data()
{
    if (!compact()) {
        ALOGE("compact failed, the ProtoOutputStream data is corrupted!");
        mBuffer->clear();
    }
    return mBuffer->read();
}

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

