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

#ifndef AAPT_RESOURCE_TABLE_H
#define AAPT_RESOURCE_TABLE_H

#include "ConfigDescription.h"
#include "Diagnostics.h"
#include "Resource.h"
#include "ResourceValues.h"
#include "Source.h"
#include "StringPool.h"
#include "io/File.h"

#include <android-base/macros.h>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

namespace aapt {

enum class SymbolState {
    kUndefined,
    kPublic,
    kPrivate
};

/**
 * The Public status of a resource.
 */
struct Symbol {
    SymbolState state = SymbolState::kUndefined;
    Source source;
    std::u16string comment;
};

class ResourceConfigValue {
public:
    /**
     * The configuration for which this value is defined.
     */
    const ConfigDescription config;

    /**
     * The product for which this value is defined.
     */
    const std::string product;

    /**
     * The actual Value.
     */
    std::unique_ptr<Value> value;

    ResourceConfigValue(const ConfigDescription& config, const StringPiece& product) :
            config(config), product(product.toString()) { }

private:
    DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
};

/**
 * Represents a resource entry, which may have
 * varying values for each defined configuration.
 */
class ResourceEntry {
public:
    /**
     * The name of the resource. Immutable, as
     * this determines the order of this resource
     * when doing lookups.
     */
    const std::u16string name;

    /**
     * The entry ID for this resource.
     */
    Maybe<uint16_t> id;

    /**
     * Whether this resource is public (and must maintain the same entry ID across builds).
     */
    Symbol symbolStatus;

    /**
     * The resource's values for each configuration.
     */
    std::vector<std::unique_ptr<ResourceConfigValue>> values;

    ResourceEntry(const StringPiece16& name) : name(name.toString()) { }

    ResourceConfigValue* findValue(const ConfigDescription& config);
    ResourceConfigValue* findValue(const ConfigDescription& config, const StringPiece& product);
    ResourceConfigValue* findOrCreateValue(const ConfigDescription& config,
                                           const StringPiece& product);
    std::vector<ResourceConfigValue*> findAllValues(const ConfigDescription& config);

private:
    DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
};

/**
 * Represents a resource type, which holds entries defined
 * for this type.
 */
class ResourceTableType {
public:
    /**
     * The logical type of resource (string, drawable, layout, etc.).
     */
    const ResourceType type;

    /**
     * The type ID for this resource.
     */
    Maybe<uint8_t> id;

    /**
     * Whether this type is public (and must maintain the same
     * type ID across builds).
     */
    Symbol symbolStatus;

    /**
     * List of resources for this type.
     */
    std::vector<std::unique_ptr<ResourceEntry>> entries;

    explicit ResourceTableType(const ResourceType type) : type(type) { }

    ResourceEntry* findEntry(const StringPiece16& name);
    ResourceEntry* findOrCreateEntry(const StringPiece16& name);

private:
    DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
};

enum class PackageType {
    System,
    Vendor,
    App,
    Dynamic
};

class ResourceTablePackage {
public:
    PackageType type = PackageType::App;
    Maybe<uint8_t> id;
    std::u16string name;

    std::vector<std::unique_ptr<ResourceTableType>> types;

    ResourceTablePackage() = default;
    ResourceTableType* findType(ResourceType type);
    ResourceTableType* findOrCreateType(const ResourceType type);

private:
    DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
};

/**
 * The container and index for all resources defined for an app. This gets
 * flattened into a binary resource table (resources.arsc).
 */
class ResourceTable {
public:
    ResourceTable() = default;

    /**
     * When a collision of resources occurs, this method decides which value to keep.
     * Returns -1 if the existing value should be chosen.
     * Returns 0 if the collision can not be resolved (error).
     * Returns 1 if the incoming value should be chosen.
     */
    static int resolveValueCollision(Value* existing, Value* incoming);

    bool addResource(const ResourceNameRef& name,
                     const ConfigDescription& config,
                     const StringPiece& product,
                     std::unique_ptr<Value> value,
                     IDiagnostics* diag);

    bool addResource(const ResourceNameRef& name,
                     const ResourceId resId,
                     const ConfigDescription& config,
                     const StringPiece& product,
                     std::unique_ptr<Value> value,
                     IDiagnostics* diag);

    bool addFileReference(const ResourceNameRef& name,
                              const ConfigDescription& config,
                              const Source& source,
                              const StringPiece16& path,
                              IDiagnostics* diag);

    bool addFileReferenceAllowMangled(const ResourceNameRef& name,
                                      const ConfigDescription& config,
                                      const Source& source,
                                      const StringPiece16& path,
                                      io::IFile* file,
                                      IDiagnostics* diag);

    /**
     * Same as addResource, but doesn't verify the validity of the name. This is used
     * when loading resources from an existing binary resource table that may have mangled
     * names.
     */
    bool addResourceAllowMangled(const ResourceNameRef& name,
                                 const ConfigDescription& config,
                                 const StringPiece& product,
                                 std::unique_ptr<Value> value,
                                 IDiagnostics* diag);

    bool addResourceAllowMangled(const ResourceNameRef& name,
                                 const ResourceId id,
                                 const ConfigDescription& config,
                                 const StringPiece& product,
                                 std::unique_ptr<Value> value,
                                 IDiagnostics* diag);

    bool setSymbolState(const ResourceNameRef& name,
                        const ResourceId resId,
                        const Symbol& symbol,
                        IDiagnostics* diag);

    bool setSymbolStateAllowMangled(const ResourceNameRef& name,
                                    const ResourceId resId,
                                    const Symbol& symbol,
                                    IDiagnostics* diag);

    struct SearchResult {
        ResourceTablePackage* package;
        ResourceTableType* type;
        ResourceEntry* entry;
    };

    Maybe<SearchResult> findResource(const ResourceNameRef& name);

    /**
     * The string pool used by this resource table. Values that reference strings must use
     * this pool to create their strings.
     *
     * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
     * When `string pool` references are destroyed (as they will be when `packages`
     * is destroyed), they decrement a refCount, which would cause invalid
     * memory access if the pool was already destroyed.
     */
    StringPool stringPool;

    /**
     * The list of packages in this table, sorted alphabetically by package name.
     */
    std::vector<std::unique_ptr<ResourceTablePackage>> packages;

    /**
     * Returns the package struct with the given name, or nullptr if such a package does not
     * exist. The empty string is a valid package and typically is used to represent the
     * 'current' package before it is known to the ResourceTable.
     */
    ResourceTablePackage* findPackage(const StringPiece16& name);

    ResourceTablePackage* findPackageById(uint8_t id);

    ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});

private:
    ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);

    bool addFileReferenceImpl(const ResourceNameRef& name,
                              const ConfigDescription& config,
                              const Source& source,
                              const StringPiece16& path,
                              io::IFile* file,
                              const char16_t* validChars,
                              IDiagnostics* diag);

    bool addResourceImpl(const ResourceNameRef& name,
                         ResourceId resId,
                         const ConfigDescription& config,
                         const StringPiece& product,
                         std::unique_ptr<Value> value,
                         const char16_t* validChars,
                         std::function<int(Value*,Value*)> conflictResolver,
                         IDiagnostics* diag);

    bool setSymbolStateImpl(const ResourceNameRef& name,
                            ResourceId resId,
                            const Symbol& symbol,
                            const char16_t* validChars,
                            IDiagnostics* diag);

    DISALLOW_COPY_AND_ASSIGN(ResourceTable);
};

} // namespace aapt

#endif // AAPT_RESOURCE_TABLE_H
