/*
* 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.
*/

#include "ChecksumCalculator.h"

#include <string.h>

// Checklist when implementing new protocol:
// 1. update CHECKSUMHELPER_MAX_VERSION
// 2. update maxChecksumSize()
// 3. update checksumByteSize()
// 4. update addBuffer, writeChecksum, resetChecksum, validate

// change CHECKSUMHELPER_MAX_VERSION when you want to update the protocol version
#define CHECKSUMHELPER_MAX_VERSION 1

// checksum buffer size
// Please add a new checksum buffer size when implementing a new protocol,
// as well as modifying the maxChecksumSize function.
static const size_t kV1ChecksumSize = 8;

static size_t maxChecksumSize() {
    return 0 > kV1ChecksumSize ? 0 : kV1ChecksumSize;
}

static const size_t kMaxChecksumSize = maxChecksumSize();

// utility macros to create checksum string at compilation time
#define CHECKSUMHELPER_VERSION_STR_PREFIX "ANDROID_EMU_CHECKSUM_HELPER_v"
#define CHECKSUMHELPER_MACRO_TO_STR(x) #x
#define CHECKSUMHELPER_MACRO_VAL_TO_STR(x) CHECKSUMHELPER_MACRO_TO_STR(x)

static const uint32_t kMaxVersion = CHECKSUMHELPER_MAX_VERSION;
static const char* kMaxVersionStrPrefix = CHECKSUMHELPER_VERSION_STR_PREFIX;
static const char* kMaxVersionStr = CHECKSUMHELPER_VERSION_STR_PREFIX CHECKSUMHELPER_MACRO_VAL_TO_STR(CHECKSUMHELPER_MAX_VERSION);

#undef CHECKSUMHELPER_MAX_VERSION
#undef CHECKSUMHELPER_VERSION_STR_PREFIX
#undef CHECKSUMHELPER_MACRO_TO_STR
#undef CHECKSUMHELPER_MACRO_VAL_TO_STR

uint32_t ChecksumCalculator::getMaxVersion() {return kMaxVersion;}
const char* ChecksumCalculator::getMaxVersionStr() {return kMaxVersionStr;}
const char* ChecksumCalculator::getMaxVersionStrPrefix() {return kMaxVersionStrPrefix;}

bool ChecksumCalculator::setVersion(uint32_t version) {
    if (version > kMaxVersion) {  // unsupported version
        LOG_CHECKSUMHELPER("%s: ChecksumCalculator Set Unsupported version Version %d\n",
                __FUNCTION__, m_version);
        return false;
    }
    if (m_isEncodingChecksum) { // setVersion is called in the middle of encoding checksums
        LOG_CHECKSUMHELPER("%s: called between addBuffer and writeChecksum\n",
                __FUNCTION__);
        return false;
    }
    m_version = version;
    LOG_CHECKSUMHELPER("%s: ChecksumCalculator Set Version %d\n", __FUNCTION__,
                m_version);
    return true;
}

size_t ChecksumCalculator::checksumByteSize() const {
    switch (m_version) {
        case 0:
            return 0;
        case 1:
            return sizeof(uint32_t) + sizeof(m_numWrite);
        default:
            return 0;
    }
}

ChecksumCalculator::ChecksumCalculator()
                : m_version(0)
                , m_numRead(0)
                , m_numWrite(0)
                , m_isEncodingChecksum(false)
                , m_v1BufferTotalLength(0)
{
}

void ChecksumCalculator::addBuffer(const void* buf, size_t packetLen) {
    m_isEncodingChecksum = true;
    switch (m_version) {
        case 1:
            m_v1BufferTotalLength += packetLen;
            break;
    }
}

bool ChecksumCalculator::writeChecksum(void* outputChecksum, size_t outputChecksumLen) {
    if (outputChecksumLen < checksumByteSize()) return false;
    char *checksumPtr = (char *)outputChecksum;
    switch (m_version) {
        case 1: { // protocol v1 is to reverse the packetLen and write it at the end
            uint32_t val = computeV1Checksum();
            memcpy(checksumPtr, &val, sizeof(val));
            memcpy(checksumPtr+sizeof(val), &m_numWrite, sizeof(m_numWrite));
            break;
        }
    }
    resetChecksum();
    m_numWrite++;
    return true;
}

void ChecksumCalculator::resetChecksum() {
    switch (m_version) {
        case 1:
            m_v1BufferTotalLength = 0;
            break;
    }
    m_isEncodingChecksum = false;
}

bool ChecksumCalculator::validate(const void* expectedChecksum, size_t expectedChecksumLen) {
    size_t checksumSize = checksumByteSize();
    if (expectedChecksumLen != checksumSize) {
        m_numRead++;
        resetChecksum();
        return false;
    }
    // buffers for computing the checksum
    unsigned char sChecksumBuffer[kMaxChecksumSize];
    switch (m_version) {
        case 1: {
            uint32_t val = computeV1Checksum();
            memcpy(sChecksumBuffer, &val, sizeof(val));
            memcpy(sChecksumBuffer+sizeof(val), &m_numRead, sizeof(m_numRead));
            break;
        }
    }
    bool isValid = !memcmp(sChecksumBuffer, expectedChecksum, checksumSize);
    m_numRead++;
    resetChecksum();
    return isValid;
}

uint32_t ChecksumCalculator::computeV1Checksum() {
    uint32_t revLen = m_v1BufferTotalLength;
    revLen = (revLen & 0xffff0000) >> 16 | (revLen & 0x0000ffff) << 16;
    revLen = (revLen & 0xff00ff00) >> 8 | (revLen & 0x00ff00ff) << 8;
    revLen = (revLen & 0xf0f0f0f0) >> 4 | (revLen & 0x0f0f0f0f) << 4;
    revLen = (revLen & 0xcccccccc) >> 2 | (revLen & 0x33333333) << 2;
    revLen = (revLen & 0xaaaaaaaa) >> 1 | (revLen & 0x55555555) << 1;
    return revLen;
}
