/*
 * Copyright (C) 2015 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 "PersistableBundle"

#include <binder/PersistableBundle.h>

#include <limits>

#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <log/log.h>
#include <utils/Errors.h>

#include "ParcelValTypes.h"

using android::binder::VAL_BOOLEAN;
using android::binder::VAL_INTEGER;
using android::binder::VAL_LONG;
using android::binder::VAL_DOUBLE;
using android::binder::VAL_STRING;
using android::binder::VAL_BOOLEANARRAY;
using android::binder::VAL_INTARRAY;
using android::binder::VAL_LONGARRAY;
using android::binder::VAL_DOUBLEARRAY;
using android::binder::VAL_STRINGARRAY;
using android::binder::VAL_PERSISTABLEBUNDLE;

using std::map;
using std::set;
using std::vector;

enum {
    // Keep them in sync with BUNDLE_MAGIC* in frameworks/base/core/java/android/os/BaseBundle.java.
    BUNDLE_MAGIC = 0x4C444E42,
    BUNDLE_MAGIC_NATIVE = 0x4C444E44,
};

namespace {
template <typename T>
bool getValue(const android::String16& key, T* out, const map<android::String16, T>& map) {
    const auto& it = map.find(key);
    if (it == map.end()) return false;
    *out = it->second;
    return true;
}

template <typename T>
set<android::String16> getKeys(const map<android::String16, T>& map) {
    if (map.empty()) return set<android::String16>();
    set<android::String16> keys;
    for (const auto& key_value_pair : map) {
        keys.emplace(key_value_pair.first);
    }
    return keys;
}
}  // namespace

namespace android {

namespace os {

#define RETURN_IF_FAILED(calledOnce)                                     \
    {                                                                    \
        status_t returnStatus = calledOnce;                              \
        if (returnStatus) {                                              \
            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
            return returnStatus;                                         \
         }                                                               \
    }

#define RETURN_IF_ENTRY_ERASED(map, key)                                 \
    {                                                                    \
        size_t num_erased = (map).erase(key);                            \
        if (num_erased) {                                                \
            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
            return num_erased;                                           \
         }                                                               \
    }

status_t PersistableBundle::writeToParcel(Parcel* parcel) const {
    /*
     * Keep implementation in sync with writeToParcelInner() in
     * frameworks/base/core/java/android/os/BaseBundle.java.
     */

    // Special case for empty bundles.
    if (empty()) {
        RETURN_IF_FAILED(parcel->writeInt32(0));
        return NO_ERROR;
    }

    size_t length_pos = parcel->dataPosition();
    RETURN_IF_FAILED(parcel->writeInt32(1));  // dummy, will hold length
    RETURN_IF_FAILED(parcel->writeInt32(BUNDLE_MAGIC_NATIVE));

    size_t start_pos = parcel->dataPosition();
    RETURN_IF_FAILED(writeToParcelInner(parcel));
    size_t end_pos = parcel->dataPosition();

    // Backpatch length. This length value includes the length header.
    parcel->setDataPosition(length_pos);
    size_t length = end_pos - start_pos;
    if (length > std::numeric_limits<int32_t>::max()) {
        ALOGE("Parcel length (%zu) too large to store in 32-bit signed int", length);
        return BAD_VALUE;
    }
    RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(length)));
    parcel->setDataPosition(end_pos);
    return NO_ERROR;
}

status_t PersistableBundle::readFromParcel(const Parcel* parcel) {
    /*
     * Keep implementation in sync with readFromParcelInner() in
     * frameworks/base/core/java/android/os/BaseBundle.java.
     */
    int32_t length = parcel->readInt32();
    if (length < 0) {
        ALOGE("Bad length in parcel: %d", length);
        return UNEXPECTED_NULL;
    }

    return readFromParcelInner(parcel, static_cast<size_t>(length));
}

bool PersistableBundle::empty() const {
    return size() == 0u;
}

size_t PersistableBundle::size() const {
    return (mBoolMap.size() +
            mIntMap.size() +
            mLongMap.size() +
            mDoubleMap.size() +
            mStringMap.size() +
            mBoolVectorMap.size() +
            mIntVectorMap.size() +
            mLongVectorMap.size() +
            mDoubleVectorMap.size() +
            mStringVectorMap.size() +
            mPersistableBundleMap.size());
}

size_t PersistableBundle::erase(const String16& key) {
    RETURN_IF_ENTRY_ERASED(mBoolMap, key);
    RETURN_IF_ENTRY_ERASED(mIntMap, key);
    RETURN_IF_ENTRY_ERASED(mLongMap, key);
    RETURN_IF_ENTRY_ERASED(mDoubleMap, key);
    RETURN_IF_ENTRY_ERASED(mStringMap, key);
    RETURN_IF_ENTRY_ERASED(mBoolVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mIntVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mLongVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mDoubleVectorMap, key);
    RETURN_IF_ENTRY_ERASED(mStringVectorMap, key);
    return mPersistableBundleMap.erase(key);
}

void PersistableBundle::putBoolean(const String16& key, bool value) {
    erase(key);
    mBoolMap[key] = value;
}

void PersistableBundle::putInt(const String16& key, int32_t value) {
    erase(key);
    mIntMap[key] = value;
}

void PersistableBundle::putLong(const String16& key, int64_t value) {
    erase(key);
    mLongMap[key] = value;
}

void PersistableBundle::putDouble(const String16& key, double value) {
    erase(key);
    mDoubleMap[key] = value;
}

void PersistableBundle::putString(const String16& key, const String16& value) {
    erase(key);
    mStringMap[key] = value;
}

void PersistableBundle::putBooleanVector(const String16& key, const vector<bool>& value) {
    erase(key);
    mBoolVectorMap[key] = value;
}

void PersistableBundle::putIntVector(const String16& key, const vector<int32_t>& value) {
    erase(key);
    mIntVectorMap[key] = value;
}

void PersistableBundle::putLongVector(const String16& key, const vector<int64_t>& value) {
    erase(key);
    mLongVectorMap[key] = value;
}

void PersistableBundle::putDoubleVector(const String16& key, const vector<double>& value) {
    erase(key);
    mDoubleVectorMap[key] = value;
}

void PersistableBundle::putStringVector(const String16& key, const vector<String16>& value) {
    erase(key);
    mStringVectorMap[key] = value;
}

void PersistableBundle::putPersistableBundle(const String16& key, const PersistableBundle& value) {
    erase(key);
    mPersistableBundleMap[key] = value;
}

bool PersistableBundle::getBoolean(const String16& key, bool* out) const {
    return getValue(key, out, mBoolMap);
}

bool PersistableBundle::getInt(const String16& key, int32_t* out) const {
    return getValue(key, out, mIntMap);
}

bool PersistableBundle::getLong(const String16& key, int64_t* out) const {
    return getValue(key, out, mLongMap);
}

bool PersistableBundle::getDouble(const String16& key, double* out) const {
    return getValue(key, out, mDoubleMap);
}

bool PersistableBundle::getString(const String16& key, String16* out) const {
    return getValue(key, out, mStringMap);
}

bool PersistableBundle::getBooleanVector(const String16& key, vector<bool>* out) const {
    return getValue(key, out, mBoolVectorMap);
}

bool PersistableBundle::getIntVector(const String16& key, vector<int32_t>* out) const {
    return getValue(key, out, mIntVectorMap);
}

bool PersistableBundle::getLongVector(const String16& key, vector<int64_t>* out) const {
    return getValue(key, out, mLongVectorMap);
}

bool PersistableBundle::getDoubleVector(const String16& key, vector<double>* out) const {
    return getValue(key, out, mDoubleVectorMap);
}

bool PersistableBundle::getStringVector(const String16& key, vector<String16>* out) const {
    return getValue(key, out, mStringVectorMap);
}

bool PersistableBundle::getPersistableBundle(const String16& key, PersistableBundle* out) const {
    return getValue(key, out, mPersistableBundleMap);
}

set<String16> PersistableBundle::getBooleanKeys() const {
    return getKeys(mBoolMap);
}

set<String16> PersistableBundle::getIntKeys() const {
    return getKeys(mIntMap);
}

set<String16> PersistableBundle::getLongKeys() const {
    return getKeys(mLongMap);
}

set<String16> PersistableBundle::getDoubleKeys() const {
    return getKeys(mDoubleMap);
}

set<String16> PersistableBundle::getStringKeys() const {
    return getKeys(mStringMap);
}

set<String16> PersistableBundle::getBooleanVectorKeys() const {
    return getKeys(mBoolVectorMap);
}

set<String16> PersistableBundle::getIntVectorKeys() const {
    return getKeys(mIntVectorMap);
}

set<String16> PersistableBundle::getLongVectorKeys() const {
    return getKeys(mLongVectorMap);
}

set<String16> PersistableBundle::getDoubleVectorKeys() const {
    return getKeys(mDoubleVectorMap);
}

set<String16> PersistableBundle::getStringVectorKeys() const {
    return getKeys(mStringVectorMap);
}

set<String16> PersistableBundle::getPersistableBundleKeys() const {
    return getKeys(mPersistableBundleMap);
}

status_t PersistableBundle::writeToParcelInner(Parcel* parcel) const {
    /*
     * To keep this implementation in sync with writeArrayMapInternal() in
     * frameworks/base/core/java/android/os/Parcel.java, the number of key
     * value pairs must be written into the parcel before writing the key-value
     * pairs themselves.
     */
    size_t num_entries = size();
    if (num_entries > std::numeric_limits<int32_t>::max()) {
        ALOGE("The size of this PersistableBundle (%zu) too large to store in 32-bit signed int",
              num_entries);
        return BAD_VALUE;
    }
    RETURN_IF_FAILED(parcel->writeInt32(static_cast<int32_t>(num_entries)));

    for (const auto& key_val_pair : mBoolMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_BOOLEAN));
        RETURN_IF_FAILED(parcel->writeBool(key_val_pair.second));
    }
    for (const auto& key_val_pair : mIntMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_INTEGER));
        RETURN_IF_FAILED(parcel->writeInt32(key_val_pair.second));
    }
    for (const auto& key_val_pair : mLongMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_LONG));
        RETURN_IF_FAILED(parcel->writeInt64(key_val_pair.second));
    }
    for (const auto& key_val_pair : mDoubleMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_DOUBLE));
        RETURN_IF_FAILED(parcel->writeDouble(key_val_pair.second));
    }
    for (const auto& key_val_pair : mStringMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_STRING));
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.second));
    }
    for (const auto& key_val_pair : mBoolVectorMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_BOOLEANARRAY));
        RETURN_IF_FAILED(parcel->writeBoolVector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mIntVectorMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_INTARRAY));
        RETURN_IF_FAILED(parcel->writeInt32Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mLongVectorMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_LONGARRAY));
        RETURN_IF_FAILED(parcel->writeInt64Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mDoubleVectorMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_DOUBLEARRAY));
        RETURN_IF_FAILED(parcel->writeDoubleVector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mStringVectorMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_STRINGARRAY));
        RETURN_IF_FAILED(parcel->writeString16Vector(key_val_pair.second));
    }
    for (const auto& key_val_pair : mPersistableBundleMap) {
        RETURN_IF_FAILED(parcel->writeString16(key_val_pair.first));
        RETURN_IF_FAILED(parcel->writeInt32(VAL_PERSISTABLEBUNDLE));
        RETURN_IF_FAILED(key_val_pair.second.writeToParcel(parcel));
    }
    return NO_ERROR;
}

status_t PersistableBundle::readFromParcelInner(const Parcel* parcel, size_t length) {
    /*
     * Note: we don't actually use length for anything other than an empty PersistableBundle
     * check, since we do not actually need to copy in an entire Parcel, unlike in the Java
     * implementation.
     */
    if (length == 0) {
        // Empty PersistableBundle or end of data.
        return NO_ERROR;
    }

    int32_t magic;
    RETURN_IF_FAILED(parcel->readInt32(&magic));
    if (magic != BUNDLE_MAGIC && magic != BUNDLE_MAGIC_NATIVE) {
        ALOGE("Bad magic number for PersistableBundle: 0x%08x", magic);
        return BAD_VALUE;
    }

    /*
     * To keep this implementation in sync with unparcel() in
     * frameworks/base/core/java/android/os/BaseBundle.java, the number of
     * key-value pairs must be read from the parcel before reading the key-value
     * pairs themselves.
     */
    int32_t num_entries;
    RETURN_IF_FAILED(parcel->readInt32(&num_entries));

    for (; num_entries > 0; --num_entries) {
        String16 key;
        int32_t value_type;
        RETURN_IF_FAILED(parcel->readString16(&key));
        RETURN_IF_FAILED(parcel->readInt32(&value_type));

        /*
         * We assume that both the C++ and Java APIs ensure that all keys in a PersistableBundle
         * are unique.
         */
        switch (value_type) {
            case VAL_STRING: {
                RETURN_IF_FAILED(parcel->readString16(&mStringMap[key]));
                break;
            }
            case VAL_INTEGER: {
                RETURN_IF_FAILED(parcel->readInt32(&mIntMap[key]));
                break;
            }
            case VAL_LONG: {
                RETURN_IF_FAILED(parcel->readInt64(&mLongMap[key]));
                break;
            }
            case VAL_DOUBLE: {
                RETURN_IF_FAILED(parcel->readDouble(&mDoubleMap[key]));
                break;
            }
            case VAL_BOOLEAN: {
                RETURN_IF_FAILED(parcel->readBool(&mBoolMap[key]));
                break;
            }
            case VAL_STRINGARRAY: {
                RETURN_IF_FAILED(parcel->readString16Vector(&mStringVectorMap[key]));
                break;
            }
            case VAL_INTARRAY: {
                RETURN_IF_FAILED(parcel->readInt32Vector(&mIntVectorMap[key]));
                break;
            }
            case VAL_LONGARRAY: {
                RETURN_IF_FAILED(parcel->readInt64Vector(&mLongVectorMap[key]));
                break;
            }
            case VAL_BOOLEANARRAY: {
                RETURN_IF_FAILED(parcel->readBoolVector(&mBoolVectorMap[key]));
                break;
            }
            case VAL_PERSISTABLEBUNDLE: {
                RETURN_IF_FAILED(mPersistableBundleMap[key].readFromParcel(parcel));
                break;
            }
            case VAL_DOUBLEARRAY: {
                RETURN_IF_FAILED(parcel->readDoubleVector(&mDoubleVectorMap[key]));
                break;
            }
            default: {
                ALOGE("Unrecognized type: %d", value_type);
                return BAD_TYPE;
                break;
            }
        }
    }

    return NO_ERROR;
}

}  // namespace os

}  // namespace android
