/*
 * 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 "ResourceTable.h"
#include "ResourceUtils.h"
#include "ValueVisitor.h"
#include "proto/ProtoHelpers.h"
#include "proto/ProtoSerialize.h"

#include <androidfw/ResourceTypes.h>

namespace aapt {

namespace {

class ReferenceIdToNameVisitor : public ValueVisitor {
public:
    using ValueVisitor::visit;

    explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping) :
            mMapping(mapping) {
        assert(mMapping);
    }

    void visit(Reference* reference) override {
        if (!reference->id || !reference->id.value().isValid()) {
            return;
        }

        ResourceId id = reference->id.value();
        auto cacheIter = mMapping->find(id);
        if (cacheIter != mMapping->end()) {
            reference->name = cacheIter->second.toResourceName();
        }
    }

private:
    const std::map<ResourceId, ResourceNameRef>* mMapping;
};

class PackagePbDeserializer {
public:
    PackagePbDeserializer(const android::ResStringPool* valuePool,
                          const android::ResStringPool* sourcePool,
                          const android::ResStringPool* symbolPool,
                          const Source& source, IDiagnostics* diag) :
            mValuePool(valuePool), mSourcePool(sourcePool), mSymbolPool(symbolPool),
            mSource(source), mDiag(diag) {
    }

public:
    bool deserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
        Maybe<uint8_t> id;
        if (pbPackage.has_package_id()) {
            id = static_cast<uint8_t>(pbPackage.package_id());
        }

        std::map<ResourceId, ResourceNameRef> idIndex;

        ResourceTablePackage* pkg = table->createPackage(pbPackage.package_name(), id);
        for (const pb::Type& pbType : pbPackage.types()) {
            const ResourceType* resType = parseResourceType(pbType.name());
            if (!resType) {
                mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name() << "'");
                return {};
            }

            ResourceTableType* type = pkg->findOrCreateType(*resType);

            for (const pb::Entry& pbEntry : pbType.entries()) {
                ResourceEntry* entry = type->findOrCreateEntry(pbEntry.name());

                // Deserialize the symbol status (public/private with source and comments).
                if (pbEntry.has_symbol_status()) {
                    const pb::SymbolStatus& pbStatus = pbEntry.symbol_status();
                    if (pbStatus.has_source()) {
                        deserializeSourceFromPb(pbStatus.source(), *mSourcePool,
                                                &entry->symbolStatus.source);
                    }

                    if (pbStatus.has_comment()) {
                        entry->symbolStatus.comment = pbStatus.comment();
                    }

                    SymbolState visibility = deserializeVisibilityFromPb(pbStatus.visibility());
                    entry->symbolStatus.state = visibility;

                    if (visibility == SymbolState::kPublic) {
                        // This is a public symbol, we must encode the ID now if there is one.
                        if (pbEntry.has_id()) {
                            entry->id = static_cast<uint16_t>(pbEntry.id());
                        }

                        if (type->symbolStatus.state != SymbolState::kPublic) {
                            // If the type has not been made public, do so now.
                            type->symbolStatus.state = SymbolState::kPublic;
                            if (pbType.has_id()) {
                                type->id = static_cast<uint8_t>(pbType.id());
                            }
                        }
                    } else if (visibility == SymbolState::kPrivate) {
                        if (type->symbolStatus.state == SymbolState::kUndefined) {
                            type->symbolStatus.state = SymbolState::kPrivate;
                        }
                    }
                }

                ResourceId resId(pbPackage.package_id(), pbType.id(), pbEntry.id());
                if (resId.isValid()) {
                    idIndex[resId] = ResourceNameRef(pkg->name, type->type, entry->name);
                }

                for (const pb::ConfigValue& pbConfigValue : pbEntry.config_values()) {
                    const pb::ConfigDescription& pbConfig = pbConfigValue.config();

                    ConfigDescription config;
                    if (!deserializeConfigDescriptionFromPb(pbConfig, &config)) {
                        mDiag->error(DiagMessage(mSource) << "invalid configuration");
                        return {};
                    }

                    ResourceConfigValue* configValue = entry->findOrCreateValue(config,
                                                                                pbConfig.product());
                    if (configValue->value) {
                        // Duplicate config.
                        mDiag->error(DiagMessage(mSource) << "duplicate configuration");
                        return {};
                    }

                    configValue->value = deserializeValueFromPb(pbConfigValue.value(),
                                                                config, &table->stringPool);
                    if (!configValue->value) {
                        return {};
                    }
                }
            }
        }

        ReferenceIdToNameVisitor visitor(&idIndex);
        visitAllValuesInPackage(pkg, &visitor);
        return true;
    }

private:
    std::unique_ptr<Item> deserializeItemFromPb(const pb::Item& pbItem,
                                                const ConfigDescription& config,
                                                StringPool* pool) {
        if (pbItem.has_ref()) {
            const pb::Reference& pbRef = pbItem.ref();
            std::unique_ptr<Reference> ref = util::make_unique<Reference>();
            if (!deserializeReferenceFromPb(pbRef, ref.get())) {
                return {};
            }
            return std::move(ref);

        } else if (pbItem.has_prim()) {
            const pb::Primitive& pbPrim = pbItem.prim();
            android::Res_value prim = {};
            prim.dataType = static_cast<uint8_t>(pbPrim.type());
            prim.data = pbPrim.data();
            return util::make_unique<BinaryPrimitive>(prim);

        } else if (pbItem.has_id()) {
            return util::make_unique<Id>();

        } else if (pbItem.has_str()) {
            const uint32_t idx = pbItem.str().idx();
            const std::string str = util::getString(*mValuePool, idx);

            const android::ResStringPool_span* spans = mValuePool->styleAt(idx);
            if (spans && spans->name.index != android::ResStringPool_span::END) {
                StyleString styleStr = { str };
                while (spans->name.index != android::ResStringPool_span::END) {
                    styleStr.spans.push_back(Span{
                            util::getString(*mValuePool, spans->name.index),
                            spans->firstChar,
                            spans->lastChar
                    });
                    spans++;
                }
                return util::make_unique<StyledString>(
                        pool->makeRef(styleStr, StringPool::Context{ 1, config }));
            }
            return util::make_unique<String>(
                    pool->makeRef(str, StringPool::Context{ 1, config }));

        } else if (pbItem.has_raw_str()) {
            const uint32_t idx = pbItem.raw_str().idx();
            const std::string str = util::getString(*mValuePool, idx);
            return util::make_unique<RawString>(
                    pool->makeRef(str, StringPool::Context{ 1, config }));

        } else if (pbItem.has_file()) {
            const uint32_t idx = pbItem.file().path_idx();
            const std::string str = util::getString(*mValuePool, idx);
            return util::make_unique<FileReference>(
                    pool->makeRef(str, StringPool::Context{ 0, config }));

        } else {
            mDiag->error(DiagMessage(mSource) << "unknown item");
        }
        return {};
    }

    std::unique_ptr<Value> deserializeValueFromPb(const pb::Value& pbValue,
                                                  const ConfigDescription& config,
                                                  StringPool* pool) {
        const bool isWeak = pbValue.has_weak() ? pbValue.weak() : false;

        std::unique_ptr<Value> value;
        if (pbValue.has_item()) {
            value = deserializeItemFromPb(pbValue.item(), config, pool);
            if (!value) {
                return {};
            }

        } else if (pbValue.has_compound_value()) {
            const pb::CompoundValue& pbCompoundValue = pbValue.compound_value();
            if (pbCompoundValue.has_attr()) {
                const pb::Attribute& pbAttr = pbCompoundValue.attr();
                std::unique_ptr<Attribute> attr = util::make_unique<Attribute>(isWeak);
                attr->typeMask = pbAttr.format_flags();
                attr->minInt = pbAttr.min_int();
                attr->maxInt = pbAttr.max_int();
                for (const pb::Attribute_Symbol& pbSymbol : pbAttr.symbols()) {
                    Attribute::Symbol symbol;
                    deserializeItemCommon(pbSymbol, &symbol.symbol);
                    if (!deserializeReferenceFromPb(pbSymbol.name(), &symbol.symbol)) {
                        return {};
                    }
                    symbol.value = pbSymbol.value();
                    attr->symbols.push_back(std::move(symbol));
                }
                value = std::move(attr);

            } else if (pbCompoundValue.has_style()) {
                const pb::Style& pbStyle = pbCompoundValue.style();
                std::unique_ptr<Style> style = util::make_unique<Style>();
                if (pbStyle.has_parent()) {
                    style->parent = Reference();
                    if (!deserializeReferenceFromPb(pbStyle.parent(), &style->parent.value())) {
                        return {};
                    }

                    if (pbStyle.has_parent_source()) {
                        Source parentSource;
                        deserializeSourceFromPb(pbStyle.parent_source(), *mSourcePool,
                                                &parentSource);
                        style->parent.value().setSource(std::move(parentSource));
                    }
                }

                for (const pb::Style_Entry& pbEntry : pbStyle.entries()) {
                    Style::Entry entry;
                    deserializeItemCommon(pbEntry, &entry.key);
                    if (!deserializeReferenceFromPb(pbEntry.key(), &entry.key)) {
                        return {};
                    }

                    entry.value = deserializeItemFromPb(pbEntry.item(), config, pool);
                    if (!entry.value) {
                        return {};
                    }

                    deserializeItemCommon(pbEntry, entry.value.get());
                    style->entries.push_back(std::move(entry));
                }
                value = std::move(style);

            } else if (pbCompoundValue.has_styleable()) {
                const pb::Styleable& pbStyleable = pbCompoundValue.styleable();
                std::unique_ptr<Styleable> styleable = util::make_unique<Styleable>();
                for (const pb::Styleable_Entry& pbEntry : pbStyleable.entries()) {
                    Reference attrRef;
                    deserializeItemCommon(pbEntry, &attrRef);
                    deserializeReferenceFromPb(pbEntry.attr(), &attrRef);
                    styleable->entries.push_back(std::move(attrRef));
                }
                value = std::move(styleable);

            } else if (pbCompoundValue.has_array()) {
                const pb::Array& pbArray = pbCompoundValue.array();
                std::unique_ptr<Array> array = util::make_unique<Array>();
                for (const pb::Array_Entry& pbEntry : pbArray.entries()) {
                    std::unique_ptr<Item> item = deserializeItemFromPb(pbEntry.item(), config,
                                                                       pool);
                    if (!item) {
                        return {};
                    }

                    deserializeItemCommon(pbEntry, item.get());
                    array->items.push_back(std::move(item));
                }
                value = std::move(array);

            } else if (pbCompoundValue.has_plural()) {
                const pb::Plural& pbPlural = pbCompoundValue.plural();
                std::unique_ptr<Plural> plural = util::make_unique<Plural>();
                for (const pb::Plural_Entry& pbEntry : pbPlural.entries()) {
                    size_t pluralIdx = deserializePluralEnumFromPb(pbEntry.arity());
                    plural->values[pluralIdx] = deserializeItemFromPb(pbEntry.item(), config,
                                                                      pool);
                    if (!plural->values[pluralIdx]) {
                        return {};
                    }

                    deserializeItemCommon(pbEntry, plural->values[pluralIdx].get());
                }
                value = std::move(plural);

            } else {
                mDiag->error(DiagMessage(mSource) << "unknown compound value");
                return {};
            }
        } else {
            mDiag->error(DiagMessage(mSource) << "unknown value");
            return {};
        }

        assert(value && "forgot to set value");

        value->setWeak(isWeak);
        deserializeItemCommon(pbValue, value.get());
        return value;
    }

    bool deserializeReferenceFromPb(const pb::Reference& pbRef, Reference* outRef) {
        outRef->referenceType = deserializeReferenceTypeFromPb(pbRef.type());
        outRef->privateReference = pbRef.private_();

        if (!pbRef.has_id() && !pbRef.has_symbol_idx()) {
            return false;
        }

        if (pbRef.has_id()) {
            outRef->id = ResourceId(pbRef.id());
        }

        if (pbRef.has_symbol_idx()) {
            const std::string strSymbol = util::getString(*mSymbolPool, pbRef.symbol_idx());
            ResourceNameRef nameRef;
            if (!ResourceUtils::parseResourceName(strSymbol, &nameRef, nullptr)) {
                mDiag->error(DiagMessage(mSource) << "invalid reference name '"
                             << strSymbol << "'");
                return false;
            }

            outRef->name = nameRef.toResourceName();
        }
        return true;
    }

    template <typename T>
    void deserializeItemCommon(const T& pbItem, Value* outValue) {
        if (pbItem.has_source()) {
            Source source;
            deserializeSourceFromPb(pbItem.source(), *mSourcePool, &source);
            outValue->setSource(std::move(source));
        }

        if (pbItem.has_comment()) {
            outValue->setComment(pbItem.comment());
        }
    }

private:
    const android::ResStringPool* mValuePool;
    const android::ResStringPool* mSourcePool;
    const android::ResStringPool* mSymbolPool;
    const Source mSource;
    IDiagnostics* mDiag;
};

} // namespace

std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
                                                      const Source& source,
                                                      IDiagnostics* diag) {
    // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
    // causes errors when qualifying it with android::
    using namespace android;

    std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();

    if (!pbTable.has_string_pool()) {
        diag->error(DiagMessage(source) << "no string pool found");
        return {};
    }

    ResStringPool valuePool;
    status_t result = valuePool.setTo(pbTable.string_pool().data().data(),
                                      pbTable.string_pool().data().size());
    if (result != NO_ERROR) {
        diag->error(DiagMessage(source) << "invalid string pool");
        return {};
    }

    ResStringPool sourcePool;
    if (pbTable.has_source_pool()) {
        result = sourcePool.setTo(pbTable.source_pool().data().data(),
                                  pbTable.source_pool().data().size());
        if (result != NO_ERROR) {
            diag->error(DiagMessage(source) << "invalid source pool");
            return {};
        }
    }

    ResStringPool symbolPool;
    if (pbTable.has_symbol_pool()) {
        result = symbolPool.setTo(pbTable.symbol_pool().data().data(),
                                  pbTable.symbol_pool().data().size());
        if (result != NO_ERROR) {
            diag->error(DiagMessage(source) << "invalid symbol pool");
            return {};
        }
    }

    PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool, &symbolPool, source, diag);
    for (const pb::Package& pbPackage : pbTable.packages()) {
        if (!packagePbDeserializer.deserializeFromPb(pbPackage, table.get())) {
            return {};
        }
    }
    return table;
}

std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(const pb::CompiledFile& pbFile,
                                                            const Source& source,
                                                            IDiagnostics* diag) {
    std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();

    ResourceNameRef nameRef;

    // Need to create an lvalue here so that nameRef can point to something real.
    if (!ResourceUtils::parseResourceName(pbFile.resource_name(), &nameRef)) {
        diag->error(DiagMessage(source) << "invalid resource name in compiled file header: "
                    << pbFile.resource_name());
        return {};
    }
    file->name = nameRef.toResourceName();
    file->source.path = pbFile.source_path();
    deserializeConfigDescriptionFromPb(pbFile.config(), &file->config);

    for (const pb::CompiledFile_Symbol& pbSymbol : pbFile.exported_symbols()) {
        // Need to create an lvalue here so that nameRef can point to something real.
        if (!ResourceUtils::parseResourceName(pbSymbol.resource_name(), &nameRef)) {
            diag->error(DiagMessage(source) << "invalid resource name for exported symbol in "
                                               "compiled file header: "
                                            << pbFile.resource_name());
            return {};
        }
        file->exportedSymbols.push_back(
                SourcedResourceName{ nameRef.toResourceName(), pbSymbol.line_no() });
    }
    return file;
}

} // namespace aapt
