/*
 * Copyright (C) 2009 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 "backup_data"

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <androidfw/BackupHelpers.h>
#include <log/log.h>
#include <utils/ByteOrder.h>

namespace android {

static const bool kIsDebug = false;

/*
 * File Format (v1):
 *
 * All ints are stored little-endian.
 *
 *  - An app_header_v1 struct.
 *  - The name of the package, utf-8, null terminated, padded to 4-byte boundary.
 *  - A sequence of zero or more key/value paires (entities), each with
 *      - A entity_header_v1 struct
 *      - The key, utf-8, null terminated, padded to 4-byte boundary.
 *      - The value, padded to 4 byte boundary
 */

const static int ROUND_UP[4] = { 0, 3, 2, 1 };

static inline size_t
padding_extra(size_t n)
{
    return ROUND_UP[n % 4];
}

BackupDataWriter::BackupDataWriter(int fd)
    :m_fd(fd),
     m_status(NO_ERROR),
     m_entityCount(0)
{
    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
    if (kIsDebug) ALOGI("BackupDataWriter(%d) @ %ld", fd, (long)m_pos);
}

BackupDataWriter::~BackupDataWriter()
{
}

// Pad out anything they've previously written to the next 4 byte boundary.
status_t
BackupDataWriter::write_padding_for(int n)
{
    ssize_t amt;
    ssize_t paddingSize;

    paddingSize = padding_extra(n);
    if (paddingSize > 0) {
        uint32_t padding = 0xbcbcbcbc;
        if (kIsDebug) ALOGI("writing %zd padding bytes for %d", paddingSize, n);
        amt = write(m_fd, &padding, paddingSize);
        if (amt != paddingSize) {
            m_status = errno;
            return m_status;
        }
        m_pos += amt;
    }
    return NO_ERROR;
}

status_t
BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
{
    if (m_status != NO_ERROR) {
        return m_status;
    }

    ssize_t amt;

    amt = write_padding_for(m_pos);
    if (amt != 0) {
        return amt;
    }

    String8 k;
    if (m_keyPrefix.length() > 0) {
        k = m_keyPrefix;
        k += ":";
        k += key;
    } else {
        k = key;
    }
    if (kIsDebug) {
        ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.c_str(),
                key.c_str(), dataSize);
    }

    entity_header_v1 header;
    ssize_t keyLen;

    keyLen = k.length();

    header.type = tolel(BACKUP_HEADER_ENTITY_V1);
    header.keyLen = tolel(keyLen);
    header.dataSize = tolel(dataSize);

    if (kIsDebug) ALOGI("writing entity header, %zu bytes", sizeof(entity_header_v1));
    amt = write(m_fd, &header, sizeof(entity_header_v1));
    if (amt != sizeof(entity_header_v1)) {
        m_status = errno;
        return m_status;
    }
    m_pos += amt;

    if (kIsDebug) ALOGI("writing entity header key, %zd bytes", keyLen+1);
    amt = write(m_fd, k.c_str(), keyLen+1);
    if (amt != keyLen+1) {
        m_status = errno;
        return m_status;
    }
    m_pos += amt;

    amt = write_padding_for(keyLen+1);

    m_entityCount++;

    return amt;
}

status_t
BackupDataWriter::WriteEntityData(const void* data, size_t size)
{
    if (kIsDebug) ALOGD("Writing data: size=%lu", (unsigned long) size);

    if (m_status != NO_ERROR) {
        if (kIsDebug) {
            ALOGD("Not writing data - stream in error state %d (%s)", m_status, strerror(m_status));
        }
        return m_status;
    }

    // We don't write padding here, because they're allowed to call this several
    // times with smaller buffers.  We write it at the end of WriteEntityHeader
    // instead.
    ssize_t amt = write(m_fd, data, size);
    if (amt != (ssize_t)size) {
        m_status = errno;
        if (kIsDebug) ALOGD("write returned error %d (%s)", m_status, strerror(m_status));
        return m_status;
    }
    m_pos += amt;
    return NO_ERROR;
}

void
BackupDataWriter::SetKeyPrefix(const String8& keyPrefix)
{
    m_keyPrefix = keyPrefix;
}


BackupDataReader::BackupDataReader(int fd)
    :m_fd(fd),
     m_done(false),
     m_status(NO_ERROR),
     m_entityCount(0)
{
    memset(&m_header, 0, sizeof(m_header));
    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
    if (kIsDebug) ALOGI("BackupDataReader(%d) @ %ld", fd, (long)m_pos);
}

BackupDataReader::~BackupDataReader()
{
}

status_t
BackupDataReader::Status()
{
    return m_status;
}

#define CHECK_SIZE(actual, expected) \
    do { \
        if ((actual) != (expected)) { \
            if ((actual) == 0) { \
                m_status = EIO; \
                m_done = true; \
            } else { \
                m_status = errno; \
                ALOGD("CHECK_SIZE(a=%ld e=%ld) failed at line %d m_status='%s'", \
                    long(actual), long(expected), __LINE__, strerror(m_status)); \
            } \
            return m_status; \
        } \
    } while(0)
#define SKIP_PADDING() \
    do { \
        status_t err = skip_padding(); \
        if (err != NO_ERROR) { \
            ALOGD("SKIP_PADDING FAILED at line %d", __LINE__); \
            m_status = err; \
            return err; \
        } \
    } while(0)

status_t
BackupDataReader::ReadNextHeader(bool* done, int* type)
{
    *done = m_done;
    if (m_status != NO_ERROR) {
        return m_status;
    }

    int amt;

    amt = skip_padding();
    if (amt == EIO) {
        *done = m_done = true;
        return NO_ERROR;
    }
    else if (amt != NO_ERROR) {
        return amt;
    }
    amt = read(m_fd, &m_header, sizeof(m_header));
    *done = m_done = (amt == 0);
    if (*done) {
        return NO_ERROR;
    }
    CHECK_SIZE(amt, sizeof(m_header));
    m_pos += sizeof(m_header);
    if (type) {
        *type = m_header.type;
    }

    // validate and fix up the fields.
    m_header.type = fromlel(m_header.type);
    switch (m_header.type)
    {
        case BACKUP_HEADER_ENTITY_V1:
        {
            m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
            if (m_header.entity.keyLen <= 0) {
                ALOGD("Entity header at %d has keyLen<=0: 0x%08x\n", (int)m_pos,
                        (int)m_header.entity.keyLen);
                m_status = EINVAL;
            }
            m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
            m_entityCount++;

            // read the rest of the header (filename)
            size_t size = m_header.entity.keyLen;
            char* buf = m_key.lockBuffer(size);
            if (buf == NULL) {
                m_status = ENOMEM;
                return m_status;
            }
            int amt = read(m_fd, buf, size+1);
            CHECK_SIZE(amt, (int)size+1);
            m_key.unlockBuffer(size);
            m_pos += size+1;
            SKIP_PADDING();
            m_dataEndPos = m_pos + m_header.entity.dataSize;

            break;
        }
        default:
            ALOGD("Chunk header at %d has invalid type: 0x%08x",
                    (int)(m_pos - sizeof(m_header)), (int)m_header.type);
            m_status = EINVAL;
    }

    return m_status;
}

bool
BackupDataReader::HasEntities()
{
    return m_status == NO_ERROR && m_header.type == BACKUP_HEADER_ENTITY_V1;
}

status_t
BackupDataReader::ReadEntityHeader(String8* key, size_t* dataSize)
{
    if (m_status != NO_ERROR) {
        return m_status;
    }
    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
        return EINVAL;
    }
    *key = m_key;
    *dataSize = m_header.entity.dataSize;
    return NO_ERROR;
}

status_t
BackupDataReader::SkipEntityData()
{
    if (m_status != NO_ERROR) {
        return m_status;
    }
    if (m_header.type != BACKUP_HEADER_ENTITY_V1) {
        return EINVAL;
    }
    if (m_header.entity.dataSize > 0) {
        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
        if (pos == -1) {
            return errno;
        }
        m_pos = pos;
    }
    SKIP_PADDING();
    return NO_ERROR;
}

ssize_t
BackupDataReader::ReadEntityData(void* data, size_t size)
{
    if (m_status != NO_ERROR) {
        return -1;
    }
    int remaining = m_dataEndPos - m_pos;
    if (kIsDebug) {
        ALOGD("ReadEntityData size=%zu m_pos=0x%zx m_dataEndPos=0x%zx remaining=%d\n",
                size, m_pos, m_dataEndPos, remaining);
    }
    if (remaining <= 0) {
        return 0;
    }
    if (((int)size) > remaining) {
        size = remaining;
    }
    if (kIsDebug) {
        ALOGD("   reading %zu bytes", size);
    }
    int amt = read(m_fd, data, size);
    if (amt < 0) {
        m_status = errno;
        return -1;
    }
    if (amt == 0) {
        m_status = EIO;
        m_done = true;
    }
    m_pos += amt;
    return amt;
}

status_t
BackupDataReader::skip_padding()
{
    ssize_t amt;
    ssize_t paddingSize;

    paddingSize = padding_extra(m_pos);
    if (paddingSize > 0) {
        uint32_t padding;
        amt = read(m_fd, &padding, paddingSize);
        CHECK_SIZE(amt, paddingSize);
        m_pos += amt;
    }
    return NO_ERROR;
}


} // namespace android
