/*
 * 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 "Resource.h"
#include "ResourceValues.h"
#include "Source.h"
#include "StringPool.h"

#include <memory>
#include <string>
#include <tuple>
#include <vector>

namespace aapt {

/**
 * The Public status of a resource.
 */
struct Public {
    bool isPublic = false;
    std::u16string comment;
};

/**
 * The resource value for a specific configuration.
 */
struct ResourceConfigValue {
    ConfigDescription config;
    SourceLine source;
    std::u16string comment;
    std::unique_ptr<Value> value;
};

/**
 * Represents a resource entry, which may have
 * varying values for each defined configuration.
 */
struct ResourceEntry {
    enum {
        kUnsetEntryId = 0xffffffffu
    };

    /**
     * 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.
     */
    size_t entryId;

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

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

    inline ResourceEntry(const StringPiece16& _name);
    inline ResourceEntry(const ResourceEntry* rhs);
};

/**
 * Represents a resource type, which holds entries defined
 * for this type.
 */
struct ResourceTableType {
    enum {
        kUnsetTypeId = 0xffffffffu
    };

    /**
     * The logical type of resource (string, drawable, layout, etc.).
     */
    const ResourceType type;

    /**
     * The type ID for this resource.
     */
    size_t typeId;

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

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

    ResourceTableType(const ResourceType _type);
    ResourceTableType(const ResourceTableType* rhs);
};

/**
 * The container and index for all resources defined for an app. This gets
 * flattened into a binary resource table (resources.arsc).
 */
class ResourceTable {
public:
    using iterator = std::vector<std::unique_ptr<ResourceTableType>>::iterator;
    using const_iterator = std::vector<std::unique_ptr<ResourceTableType>>::const_iterator;

    enum {
        kUnsetPackageId = 0xffffffff
    };

    ResourceTable();

    size_t getPackageId() const;
    void setPackageId(size_t packageId);

    const std::u16string& getPackage() const;
    void setPackage(const StringPiece16& package);

    bool addResource(const ResourceNameRef& name, const ConfigDescription& config,
                     const SourceLine& source, std::unique_ptr<Value> value);

    bool addResource(const ResourceNameRef& name, const ResourceId resId,
                     const ConfigDescription& config, const SourceLine& source,
                     std::unique_ptr<Value> value);

    bool markPublic(const ResourceNameRef& name, const ResourceId resId, const SourceLine& source);

    /**
     * Returns the string pool used by this ResourceTable.
     * Values that reference strings should use this pool to create
     * their strings.
     */
    StringPool& getValueStringPool();
    const StringPool& getValueStringPool() const;

    std::tuple<const ResourceTableType*, const ResourceEntry*>
    findResource(const ResourceNameRef& name) const;

    iterator begin();
    iterator end();
    const_iterator begin() const;
    const_iterator end() const;

private:
    std::unique_ptr<ResourceTableType>& findOrCreateType(ResourceType type);
    std::unique_ptr<ResourceEntry>& findOrCreateEntry(std::unique_ptr<ResourceTableType>& type,
                                                      const StringPiece16& name);

    std::u16string mPackage;
    size_t mPackageId;

    // StringPool must come before mTypes so that it is destroyed after.
    // When StringPool references are destroyed (as they will be when mTypes
    // is destroyed), they decrement a refCount, which would cause invalid
    // memory access if the pool was already destroyed.
    StringPool mValuePool;

    std::vector<std::unique_ptr<ResourceTableType>> mTypes;
};

//
// ResourceEntry implementation.
//

inline ResourceEntry::ResourceEntry(const StringPiece16& _name) :
        name(_name.toString()), entryId(kUnsetEntryId) {
}

inline ResourceEntry::ResourceEntry(const ResourceEntry* rhs) :
        name(rhs->name), entryId(rhs->entryId), publicStatus(rhs->publicStatus) {
}

//
// ResourceTableType implementation.
//

inline ResourceTableType::ResourceTableType(const ResourceType _type) :
        type(_type), typeId(kUnsetTypeId) {
}

inline ResourceTableType::ResourceTableType(const ResourceTableType* rhs) :
        type(rhs->type), typeId(rhs->typeId), publicStatus(rhs->publicStatus) {
}

//
// ResourceTable implementation.
//

inline StringPool& ResourceTable::getValueStringPool() {
    return mValuePool;
}

inline const StringPool& ResourceTable::getValueStringPool() const {
    return mValuePool;
}

inline ResourceTable::iterator ResourceTable::begin() {
    return mTypes.begin();
}

inline ResourceTable::iterator ResourceTable::end() {
    return mTypes.end();
}

inline ResourceTable::const_iterator ResourceTable::begin() const {
    return mTypes.begin();
}

inline ResourceTable::const_iterator ResourceTable::end() const {
    return mTypes.end();
}

inline const std::u16string& ResourceTable::getPackage() const {
    return mPackage;
}

inline size_t ResourceTable::getPackageId() const {
    return mPackageId;
}

inline void ResourceTable::setPackage(const StringPiece16& package) {
    mPackage = package.toString();
}

inline void ResourceTable::setPackageId(size_t packageId) {
    mPackageId = packageId;
}

} // namespace aapt

#endif // AAPT_RESOURCE_TABLE_H
