/*
* Copyright (C) 2016 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.
*/

#pragma once

#include <stdint.h>
#include <stdlib.h>

// Set TRACE_CHECKSUMHELPER to 1 to debug creation/destruction of GLprotocol
// instances.
#define TRACE_CHECKSUMHELPER 0

#if TRACE_CHECKSUMHELPER
#define LOG_CHECKSUMHELPER(x...) fprintf(stderr, x)
#else
#define LOG_CHECKSUMHELPER(x...)
#endif

// ChecksumCalculator adds checksum as an array of bytes to GL pipe communication, which
// size depends on the protocol version. Each pipe should use one ChecksumCalculator.
// It can:
//      (1) take a list of buffers one by one and compute their checksum string,
//          in this case the checksum should be as the data in those buffers are
//          concatenated;
//      (2) compute the checksum of the buffer list, then either write them into
//          a buffer provided by user, or compare it against a checksum provided
//          by user
//      (3) support different checksum version in future.
//
// For backward compatibility, checksum version 0 behaves the same as there is
// no checksum (i.e., checksumByteSize returns 0, validate always returns true,
// addBuffer and writeCheckSum does nothing).
//
// Notice that to detect package lost, ChecksumCalculator also keeps track of how
// many times it generates/validates checksums, and might use it as part of the
// checksum.
//
// To evaluate checksums from a list of data buffers buf1, buf2... Please call
// addBuffer(buf1, buf1len), addBuffer(buf2, buf2len) ... in order.
// Then if the checksum needs to be encoded into a buffer, one needs to allocate
// a checksum buffer with size checksumByteSize(), and call
// writeChecksum(checksumBuffer) to write the checksum to the buffer.
// If the checksum needs to be validated against an existing one, one needs to
// call validate(existChecksum, existChecksumLen).
//
// The checksum generator and validator must be set to the same version, and
// the validator must check ALL checksums in the order they are generated,
// otherwise the validation function will return false.
//
// It is allowed to change the checksum version between calculating two
// checksums. This is designed for backward compatibility reason.
//
// Example 1, encoding and decoding:
//
// bool testChecksum(void* buf, size_t bufLen) {
//     // encoding message
//     ChecksumCalculator encoder;
//     encoder.setVersion(1);
//     encoder.addBuffer(buf, bufLen);
//     std::vector<unsigned char> message(bufLen + encoder.checksumByteSize());
//     memcpy(&message[0], buf, bufLen);
//     encoder.writeChecksum(&message[0] + bufLen, encoder.checksumByteSize());
//
//     // decoding message
//     ChecksumCalculator decoder;
//     decoder.setVersion(1);
//     decoder.addBuffer(&message[0], bufLen);
//     return decoder.validate(&message[0] + bufLen, decoder.checksumByteSize());
// }
// The return value is true.
//
// Example 2, decoding will fail if the order of messages is wrong:
//
// bool testChecksumOrder(void* buf1, size_t bufLen1,
//                        void* buf2, size_t bufLen2) {
//     // encoding messages
//     ChecksumCalculator encoder;
//     encoder.setVersion(1);
//
//     std::vector<unsigned char> message1(bufLen1 + encoder.checksumByteSize());
//     std::vector<unsigned char> message2(bufLen2 + encoder.checksumByteSize());
//
//     encoder.addBuffer(buf1, bufLen1);
//     std::vector<unsigned char> message1(bufLen1 + encoder.checksumByteSize());
//     memcpy(&message1[0], buf1, bufLen1);
//     encoder.writeChecksum(&message1[0] + bufLen1, encoder.checksumByteSize());
//
//     encoder.addBuffer(buf2, bufLen2);
//     std::vector<unsigned char> message2(bufLen2 + encoder.checksumByteSize());
//     memcpy(&message2[0], buf2, bufLen2);
//     encoder.writeChecksum(&message2[0] + bufLen2, encoder.checksumByteSize());
//
//     // decoding messages
//     ChecksumCalculator decoder;
//     decoder.setVersion(1);
//     decoder.addBuffer(&message2[0], bufLen2);
//     // returns false because the decoding order is not consistent with
//     // encoding order
//     if (!decoder.validate(&message2[0]+bufLen2, decoder.checksumByteSize())) {
//         return false;
//     }
//
//     decoder.addBuffer(&message1[0], bufLen1);
//     if (!decoder.validate(&message1[0]+bufLen1, decoder.checksumByteSize())) {
//         return false;
//     }
//
//     return false;
// }

class ChecksumCalculator {
public:
    enum Sizes {
        kVersion1ChecksumSize = 8,
        kMaxChecksumSize = kVersion1ChecksumSize
    };

    ChecksumCalculator();
    // Get and set current checksum version
    uint32_t getVersion() const { return m_version; }
    // Call setVersion to set a checksum version. It should be called before
    // addBuffer(), writeChecksum() and validate(). And it should be called
    // exact once per rendering thread if both host and guest support checksum.
    // It won't be called if either host or guest does not support checksum.
    bool setVersion(uint32_t version);

    // Maximum supported checksum version
    static uint32_t getMaxVersion();
    // A version string that looks like "ANDROID_EMU_CHECKSUM_HELPER_v1"
    // Used multiple times when the guest queries the maximum supported version
    // from the host.
    // The library owns the returned pointer. The returned pointer will be
    // deconstructed when unloading library.
    static const char* getMaxVersionStr();
    static const char* getMaxVersionStrPrefix();

    // Size of checksum in the current version
    size_t checksumByteSize() const;

    // Update the current checksum value from the data
    // at |buf| of |bufLen| bytes. Once all buffers
    // have been added, call writeChecksum() to store
    // the final checksum value and reset its state.
    void addBuffer(const void* buf, size_t bufLen);
    // Write the checksum from the list of buffers to outputChecksum
    // Will reset the list of buffers by calling resetChecksum.
    // Return false if the buffer is not long enough
    // Please query buffer size from checksumByteSize()
    bool writeChecksum(void* outputChecksum, size_t outputChecksumLen);
    // Restore the states for computing checksums.
    // Automatically called at the end of writeChecksum and validate.
    // Can also be used to abandon the current checksum being calculated.
    // Notes: it doesn't update the internal read / write counter
    void resetChecksum();

    // Calculate the checksum from the list of buffers and
    // compare it with the checksum encoded in expectedChecksum
    // Will reset the list of buffers by calling resetChecksum.
    bool validate(const void* expectedChecksum, size_t expectedChecksumLen);
protected:
    uint32_t m_version;
    // A temporary state used to compute the total length of a list of buffers,
    // if addBuffer is called.
    uint32_t m_numRead;
    uint32_t m_numWrite;
    // m_isEncodingChecksum is true when between addBuffer and writeChecksum
    bool m_isEncodingChecksum;
private:
    // Compute a 32bit checksum
    // Used in protocol v1
    uint32_t computeV1Checksum();
    // The buffer used in protocol version 1 to compute checksum.
    uint32_t m_v1BufferTotalLength;
};
