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

#include "ConfigDescription.h"
#include "Resource.h"
#include "ResourceUtils.h"
#include "ValueVisitor.h"
#include "process/SymbolTable.h"
#include "util/Util.h"

#include <androidfw/AssetManager.h>
#include <androidfw/ResourceTypes.h>

namespace aapt {

void SymbolTable::appendSource(std::unique_ptr<ISymbolSource> source) {
    mSources.push_back(std::move(source));

    // We do not clear the cache, because sources earlier in the list take precedent.
}

void SymbolTable::prependSource(std::unique_ptr<ISymbolSource> source) {
    mSources.insert(mSources.begin(), std::move(source));

    // We must clear the cache in case we did a lookup before adding this resource.
    mCache.clear();
}

const SymbolTable::Symbol* SymbolTable::findByName(const ResourceName& name) {
    if (const std::shared_ptr<Symbol>& s = mCache.get(name)) {
        return s.get();
    }

    // We did not find it in the cache, so look through the sources.
    for (auto& symbolSource : mSources) {
        std::unique_ptr<Symbol> symbol = symbolSource->findByName(name);
        if (symbol) {
            // Take ownership of the symbol into a shared_ptr. We do this because LruCache
            // doesn't support unique_ptr.
            std::shared_ptr<Symbol> sharedSymbol = std::shared_ptr<Symbol>(symbol.release());
            mCache.put(name, sharedSymbol);

            if (sharedSymbol->id) {
                // The symbol has an ID, so we can also cache this!
                mIdCache.put(sharedSymbol->id.value(), sharedSymbol);
            }
            return sharedSymbol.get();
        }
    }
    return nullptr;
}

const SymbolTable::Symbol* SymbolTable::findById(const ResourceId& id) {
    if (const std::shared_ptr<Symbol>& s = mIdCache.get(id)) {
        return s.get();
    }

    // We did not find it in the cache, so look through the sources.
    for (auto& symbolSource : mSources) {
        std::unique_ptr<Symbol> symbol = symbolSource->findById(id);
        if (symbol) {
            // Take ownership of the symbol into a shared_ptr. We do this because LruCache
            // doesn't support unique_ptr.
            std::shared_ptr<Symbol> sharedSymbol = std::shared_ptr<Symbol>(symbol.release());
            mIdCache.put(id, sharedSymbol);
            return sharedSymbol.get();
        }
    }
    return nullptr;
}

const SymbolTable::Symbol* SymbolTable::findByReference(const Reference& ref) {
    // First try the ID. This is because when we lookup by ID, we only fill in the ID cache.
    // Looking up by name fills in the name and ID cache. So a cache miss will cause a failed
    // ID lookup, then a successful name lookup. Subsequent look ups will hit immediately
    // because the ID is cached too.
    //
    // If we looked up by name first, a cache miss would mean we failed to lookup by name, then
    // succeeded to lookup by ID. Subsequent lookups will miss then hit.
    const SymbolTable::Symbol* symbol = nullptr;
    if (ref.id) {
        symbol = findById(ref.id.value());
    }

    if (ref.name && !symbol) {
        symbol = findByName(ref.name.value());
    }
    return symbol;
}

std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName(
        const ResourceName& name) {
    Maybe<ResourceTable::SearchResult> result = mTable->findResource(name);
    if (!result) {
        if (name.type == ResourceType::kAttr) {
            // Recurse and try looking up a private attribute.
            return findByName(ResourceName(name.package, ResourceType::kAttrPrivate, name.entry));
        }
        return {};
    }

    ResourceTable::SearchResult sr = result.value();

    std::unique_ptr<SymbolTable::Symbol> symbol = util::make_unique<SymbolTable::Symbol>();
    symbol->isPublic = (sr.entry->symbolStatus.state == SymbolState::kPublic);

    if (sr.package->id && sr.type->id && sr.entry->id) {
        symbol->id = ResourceId(sr.package->id.value(), sr.type->id.value(), sr.entry->id.value());
    }

    if (name.type == ResourceType::kAttr || name.type == ResourceType::kAttrPrivate) {
        const ConfigDescription kDefaultConfig;
        ResourceConfigValue* configValue = sr.entry->findValue(kDefaultConfig);
        if (configValue) {
            // This resource has an Attribute.
            if (Attribute* attr = valueCast<Attribute>(configValue->value.get())) {
                symbol->attribute = std::make_shared<Attribute>(*attr);
            } else {
                return {};
            }
        }
    }
    return symbol;
}

bool AssetManagerSymbolSource::addAssetPath(const StringPiece& path) {
    int32_t cookie = 0;
    return mAssets.addAssetPath(android::String8(path.data(), path.size()), &cookie);
}

static std::unique_ptr<SymbolTable::Symbol> lookupAttributeInTable(const android::ResTable& table,
                                                                   ResourceId id) {
    // Try as a bag.
    const android::ResTable::bag_entry* entry;
    ssize_t count = table.lockBag(id.id, &entry);
    if (count < 0) {
        table.unlockBag(entry);
        return nullptr;
    }

    // We found a resource.
    std::unique_ptr<SymbolTable::Symbol> s = util::make_unique<SymbolTable::Symbol>();
    s->id = id;

    // Check to see if it is an attribute.
    for (size_t i = 0; i < (size_t) count; i++) {
        if (entry[i].map.name.ident == android::ResTable_map::ATTR_TYPE) {
            s->attribute = std::make_shared<Attribute>(false);
            s->attribute->typeMask = entry[i].map.value.data;
            break;
        }
    }

    if (s->attribute) {
        for (size_t i = 0; i < (size_t) count; i++) {
            const android::ResTable_map& mapEntry = entry[i].map;
            if (Res_INTERNALID(mapEntry.name.ident)) {
                switch (mapEntry.name.ident) {
                case android::ResTable_map::ATTR_MIN:
                    s->attribute->minInt = static_cast<int32_t>(mapEntry.value.data);
                    break;
                case android::ResTable_map::ATTR_MAX:
                    s->attribute->maxInt = static_cast<int32_t>(mapEntry.value.data);
                    break;
                }
                continue;
            }

            android::ResTable::resource_name entryName;
            if (!table.getResourceName(mapEntry.name.ident, false, &entryName)) {
                table.unlockBag(entry);
                return nullptr;
            }

            Maybe<ResourceName> parsedName = ResourceUtils::toResourceName(entryName);
            if (!parsedName) {
                return nullptr;
            }

            Attribute::Symbol symbol;
            symbol.symbol.name = parsedName.value();
            symbol.symbol.id = ResourceId(mapEntry.name.ident);
            symbol.value = mapEntry.value.data;
            s->attribute->symbols.push_back(std::move(symbol));
        }
    }
    table.unlockBag(entry);
    return s;
}

std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByName(
        const ResourceName& name) {
    const android::ResTable& table = mAssets.getResources(false);

    const std::u16string package16 = util::utf8ToUtf16(name.package);
    const std::u16string type16 = util::utf8ToUtf16(toString(name.type));
    const std::u16string entry16 = util::utf8ToUtf16(name.entry);

    uint32_t typeSpecFlags = 0;
    ResourceId resId = table.identifierForName(entry16.data(), entry16.size(),
                                               type16.data(), type16.size(),
                                               package16.data(), package16.size(),
                                               &typeSpecFlags);
    if (!resId.isValid()) {
        return {};
    }

    std::unique_ptr<SymbolTable::Symbol> s;
    if (name.type == ResourceType::kAttr) {
        s = lookupAttributeInTable(table, resId);
    } else {
        s = util::make_unique<SymbolTable::Symbol>();
        s->id = resId;
    }

    if (s) {
        s->isPublic = (typeSpecFlags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
        return s;
    }
    return {};
}

static Maybe<ResourceName> getResourceName(const android::ResTable& table, ResourceId id) {
    android::ResTable::resource_name resName = {};
    if (!table.getResourceName(id.id, true, &resName)) {
        return {};
    }
    return ResourceUtils::toResourceName(resName);
}

std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findById(ResourceId id) {
    const android::ResTable& table = mAssets.getResources(false);
    Maybe<ResourceName> maybeName = getResourceName(table, id);
    if (!maybeName) {
        return {};
    }

    uint32_t typeSpecFlags = 0;
    table.getResourceFlags(id.id, &typeSpecFlags);

    std::unique_ptr<SymbolTable::Symbol> s;
    if (maybeName.value().type == ResourceType::kAttr) {
        s = lookupAttributeInTable(table, id);
    } else {
        s = util::make_unique<SymbolTable::Symbol>();
        s->id = id;
    }

    if (s) {
        s->isPublic = (typeSpecFlags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
        return s;
    }
    return {};
}

std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByReference(
        const Reference& ref) {
    // AssetManager always prefers IDs.
    if (ref.id) {
        return findById(ref.id.value());
    } else if (ref.name) {
        return findByName(ref.name.value());
    }
    return {};
}

} // namespace aapt
