/*
 * 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 <androidfw/BackupHelpers.h>
#include <utils/ByteOrder.h>

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

#include <cutils/log.h>

namespace android {

static const bool DEBUG = 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
round_up(size_t n)
{
    return n + ROUND_UP[n % 4];
}

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 (DEBUG) 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 (DEBUG) 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 (DEBUG) {
        ALOGD("Writing header: prefix='%s' key='%s' dataSize=%zu", m_keyPrefix.string(),
                key.string(), 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 (DEBUG) 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 (DEBUG) ALOGI("writing entity header key, %zd bytes", keyLen+1);
    amt = write(m_fd, k.string(), 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 (DEBUG) ALOGD("Writing data: size=%lu", (unsigned long) size);

    if (m_status != NO_ERROR) {
        if (DEBUG) {
            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 (DEBUG) 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 (DEBUG) 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;
    //ALOGD("ReadEntityData size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
    //        size, m_pos, m_dataEndPos, remaining);
    if (remaining <= 0) {
        return 0;
    }
    if (((int)size) > remaining) {
        size = remaining;
    }
    //ALOGD("   reading %d 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
