//
// Copyright 2006 The Android Open Source Project
//
// Information about assets being operated on.
//
#ifndef __AAPT_ASSETS_H
#define __AAPT_ASSETS_H

#include <stdlib.h>
#include <utils/AssetManager.h>
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/ResourceTypes.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/RefBase.h>
#include "ZipFile.h"

#include "Bundle.h"
#include "SourcePos.h"

using namespace android;

bool valid_symbol_name(const String8& str);

enum {
    AXIS_NONE = 0,
    AXIS_MCC = 1,
    AXIS_MNC,
    AXIS_LANGUAGE,
    AXIS_REGION,
    AXIS_SCREENLAYOUTSIZE,
    AXIS_SCREENLAYOUTLONG,
    AXIS_ORIENTATION,
    AXIS_UIMODETYPE,
    AXIS_UIMODENIGHT,
    AXIS_DENSITY,
    AXIS_TOUCHSCREEN,
    AXIS_KEYSHIDDEN,
    AXIS_KEYBOARD,
    AXIS_NAVHIDDEN,
    AXIS_NAVIGATION,
    AXIS_SCREENSIZE,
    AXIS_SMALLESTSCREENWIDTHDP,
    AXIS_SCREENWIDTHDP,
    AXIS_SCREENHEIGHTDP,
    AXIS_VERSION
};

enum {
    SDK_CUPCAKE = 3,
    SDK_DONUT = 4,
    SDK_ECLAIR = 5,
    SDK_ECLAIR_0_1 = 6,
    SDK_MR1 = 7,
    SDK_FROYO = 8,
    SDK_HONEYCOMB_MR2 = 13,
};

/**
 * This structure contains a specific variation of a single file out
 * of all the variations it can have that we can have.
 */
struct AaptGroupEntry
{
public:
    AaptGroupEntry() { }
    AaptGroupEntry(const String8& _locale, const String8& _vendor)
        : locale(_locale), vendor(_vendor) { }

    String8 mcc;
    String8 mnc;
    String8 locale;
    String8 vendor;
    String8 smallestScreenWidthDp;
    String8 screenWidthDp;
    String8 screenHeightDp;
    String8 screenLayoutSize;
    String8 screenLayoutLong;
    String8 orientation;
    String8 uiModeType;
    String8 uiModeNight;
    String8 density;
    String8 touchscreen;
    String8 keysHidden;
    String8 keyboard;
    String8 navHidden;
    String8 navigation;
    String8 screenSize;
    String8 version;

    bool initFromDirName(const char* dir, String8* resType);

    static status_t parseNamePart(const String8& part, int* axis, uint32_t* value);
    
    static bool getMccName(const char* name, ResTable_config* out = NULL);
    static bool getMncName(const char* name, ResTable_config* out = NULL);
    static bool getLocaleName(const char* name, ResTable_config* out = NULL);
    static bool getScreenLayoutSizeName(const char* name, ResTable_config* out = NULL);
    static bool getScreenLayoutLongName(const char* name, ResTable_config* out = NULL);
    static bool getOrientationName(const char* name, ResTable_config* out = NULL);
    static bool getUiModeTypeName(const char* name, ResTable_config* out = NULL);
    static bool getUiModeNightName(const char* name, ResTable_config* out = NULL);
    static bool getDensityName(const char* name, ResTable_config* out = NULL);
    static bool getTouchscreenName(const char* name, ResTable_config* out = NULL);
    static bool getKeysHiddenName(const char* name, ResTable_config* out = NULL);
    static bool getKeyboardName(const char* name, ResTable_config* out = NULL);
    static bool getNavigationName(const char* name, ResTable_config* out = NULL);
    static bool getNavHiddenName(const char* name, ResTable_config* out = NULL);
    static bool getScreenSizeName(const char* name, ResTable_config* out = NULL);
    static bool getSmallestScreenWidthDpName(const char* name, ResTable_config* out = NULL);
    static bool getScreenWidthDpName(const char* name, ResTable_config* out = NULL);
    static bool getScreenHeightDpName(const char* name, ResTable_config* out = NULL);
    static bool getVersionName(const char* name, ResTable_config* out = NULL);

    int compare(const AaptGroupEntry& o) const;

    ResTable_config toParams() const;

    inline bool operator<(const AaptGroupEntry& o) const { return compare(o) < 0; }
    inline bool operator<=(const AaptGroupEntry& o) const { return compare(o) <= 0; }
    inline bool operator==(const AaptGroupEntry& o) const { return compare(o) == 0; }
    inline bool operator!=(const AaptGroupEntry& o) const { return compare(o) != 0; }
    inline bool operator>=(const AaptGroupEntry& o) const { return compare(o) >= 0; }
    inline bool operator>(const AaptGroupEntry& o) const { return compare(o) > 0; }

    String8 toString() const;
    String8 toDirName(const String8& resType) const;
};

inline int compare_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)
{
    return lhs.compare(rhs);
}

inline int strictly_order_type(const AaptGroupEntry& lhs, const AaptGroupEntry& rhs)
{
    return compare_type(lhs, rhs) < 0;
}

class AaptGroup;

/**
 * A single asset file we know about.
 */
class AaptFile : public RefBase
{
public:
    AaptFile(const String8& sourceFile, const AaptGroupEntry& groupEntry,
             const String8& resType)
        : mGroupEntry(groupEntry)
        , mResourceType(resType)
        , mSourceFile(sourceFile)
        , mData(NULL)
        , mDataSize(0)
        , mBufferSize(0)
        , mCompression(ZipEntry::kCompressStored)
        {
            //printf("new AaptFile created %s\n", (const char*)sourceFile);
        }
    virtual ~AaptFile() {
        free(mData);
    }

    const String8& getPath() const { return mPath; }
    const AaptGroupEntry& getGroupEntry() const { return mGroupEntry; }

    // Data API.  If there is data attached to the file,
    // getSourceFile() is not used.
    bool hasData() const { return mData != NULL; }
    const void* getData() const { return mData; }
    size_t getSize() const { return mDataSize; }
    void* editData(size_t size);
    void* editData(size_t* outSize = NULL);
    void* padData(size_t wordSize);
    status_t writeData(const void* data, size_t size);
    void clearData();

    const String8& getResourceType() const { return mResourceType; }

    // File API.  If the file does not hold raw data, this is
    // a full path to a file on the filesystem that holds its data.
    const String8& getSourceFile() const { return mSourceFile; }

    String8 getPrintableSource() const;

    // Desired compression method, as per utils/ZipEntry.h.  For example,
    // no compression is ZipEntry::kCompressStored.
    int getCompressionMethod() const { return mCompression; }
    void setCompressionMethod(int c) { mCompression = c; }
private:
    friend class AaptGroup;

    String8 mPath;
    AaptGroupEntry mGroupEntry;
    String8 mResourceType;
    String8 mSourceFile;
    void* mData;
    size_t mDataSize;
    size_t mBufferSize;
    int mCompression;
};

/**
 * A group of related files (the same file, with different
 * vendor/locale variations).
 */
class AaptGroup : public RefBase
{
public:
    AaptGroup(const String8& leaf, const String8& path)
        : mLeaf(leaf), mPath(path) { }
    virtual ~AaptGroup() { }

    const String8& getLeaf() const { return mLeaf; }

    // Returns the relative path after the AaptGroupEntry dirs.
    const String8& getPath() const { return mPath; }

    const DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> >& getFiles() const
        { return mFiles; }

    status_t addFile(const sp<AaptFile>& file);
    void removeFile(size_t index);

    void print() const;

    String8 getPrintableSource() const;

private:
    String8 mLeaf;
    String8 mPath;

    DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > mFiles;
};

/**
 * A single directory of assets, which can contain for files and other
 * sub-directories.
 */
class AaptDir : public RefBase
{
public:
    AaptDir(const String8& leaf, const String8& path)
        : mLeaf(leaf), mPath(path) { }
    virtual ~AaptDir() { }

    const String8& getLeaf() const { return mLeaf; }

    const String8& getPath() const { return mPath; }

    const DefaultKeyedVector<String8, sp<AaptGroup> >& getFiles() const { return mFiles; }
    const DefaultKeyedVector<String8, sp<AaptDir> >& getDirs() const { return mDirs; }

    status_t addFile(const String8& name, const sp<AaptGroup>& file);
    status_t addDir(const String8& name, const sp<AaptDir>& dir);

    sp<AaptDir> makeDir(const String8& name);

    void removeFile(const String8& name);
    void removeDir(const String8& name);

    status_t renameFile(const sp<AaptFile>& file, const String8& newName);

    status_t addLeafFile(const String8& leafName,
                         const sp<AaptFile>& file);

    virtual ssize_t slurpFullTree(Bundle* bundle,
                                  const String8& srcDir,
                                  const AaptGroupEntry& kind,
                                  const String8& resType);

    /*
     * Perform some sanity checks on the names of files and directories here.
     * In particular:
     *  - Check for illegal chars in filenames.
     *  - Check filename length.
     *  - Check for presence of ".gz" and non-".gz" copies of same file.
     *  - Check for multiple files whose names match in a case-insensitive
     *    fashion (problematic for some systems).
     *
     * Comparing names against all other names is O(n^2).  We could speed
     * it up some by sorting the entries and being smarter about what we
     * compare against, but I'm not expecting to have enough files in a
     * single directory to make a noticeable difference in speed.
     *
     * Note that sorting here is not enough to guarantee that the package
     * contents are sorted -- subsequent updates can rearrange things.
     */
    status_t validate() const;

    void print() const;

    String8 getPrintableSource() const;

private:
    String8 mLeaf;
    String8 mPath;

    DefaultKeyedVector<String8, sp<AaptGroup> > mFiles;
    DefaultKeyedVector<String8, sp<AaptDir> > mDirs;
};

/**
 * All information we know about a particular symbol.
 */
class AaptSymbolEntry
{
public:
    AaptSymbolEntry()
        : isPublic(false), typeCode(TYPE_UNKNOWN)
    {
    }
    AaptSymbolEntry(const String8& _name)
        : name(_name), isPublic(false), typeCode(TYPE_UNKNOWN)
    {
    }
    AaptSymbolEntry(const AaptSymbolEntry& o)
        : name(o.name), sourcePos(o.sourcePos), isPublic(o.isPublic)
        , comment(o.comment), typeComment(o.typeComment)
        , typeCode(o.typeCode), int32Val(o.int32Val), stringVal(o.stringVal)
    {
    }
    AaptSymbolEntry operator=(const AaptSymbolEntry& o)
    {
        sourcePos = o.sourcePos;
        isPublic = o.isPublic;
        comment = o.comment;
        typeComment = o.typeComment;
        typeCode = o.typeCode;
        int32Val = o.int32Val;
        stringVal = o.stringVal;
        return *this;
    }
    
    const String8 name;
    
    SourcePos sourcePos;
    bool isPublic;
    
    String16 comment;
    String16 typeComment;
    
    enum {
        TYPE_UNKNOWN = 0,
        TYPE_INT32,
        TYPE_STRING
    };
    
    int typeCode;
    
    // Value.  May be one of these.
    int32_t int32Val;
    String8 stringVal;
};

/**
 * A group of related symbols (such as indices into a string block)
 * that have been generated from the assets.
 */
class AaptSymbols : public RefBase
{
public:
    AaptSymbols() { }
    virtual ~AaptSymbols() { }

    status_t addSymbol(const String8& name, int32_t value, const SourcePos& pos) {
        if (!check_valid_symbol_name(name, pos, "symbol")) {
            return BAD_VALUE;
        }
        AaptSymbolEntry& sym = edit_symbol(name, &pos);
        sym.typeCode = AaptSymbolEntry::TYPE_INT32;
        sym.int32Val = value;
        return NO_ERROR;
    }

    status_t addStringSymbol(const String8& name, const String8& value,
            const SourcePos& pos) {
        if (!check_valid_symbol_name(name, pos, "symbol")) {
            return BAD_VALUE;
        }
        AaptSymbolEntry& sym = edit_symbol(name, &pos);
        sym.typeCode = AaptSymbolEntry::TYPE_STRING;
        sym.stringVal = value;
        return NO_ERROR;
    }

    status_t makeSymbolPublic(const String8& name, const SourcePos& pos) {
        if (!check_valid_symbol_name(name, pos, "symbol")) {
            return BAD_VALUE;
        }
        AaptSymbolEntry& sym = edit_symbol(name, &pos);
        sym.isPublic = true;
        return NO_ERROR;
    }

    void appendComment(const String8& name, const String16& comment, const SourcePos& pos) {
        if (comment.size() <= 0) {
            return;
        }
        AaptSymbolEntry& sym = edit_symbol(name, &pos);
        if (sym.comment.size() == 0) {
            sym.comment = comment;
        } else {
            sym.comment.append(String16("\n"));
            sym.comment.append(comment);
        }
    }

    void appendTypeComment(const String8& name, const String16& comment) {
        if (comment.size() <= 0) {
            return;
        }
        AaptSymbolEntry& sym = edit_symbol(name, NULL);
        if (sym.typeComment.size() == 0) {
            sym.typeComment = comment;
        } else {
            sym.typeComment.append(String16("\n"));
            sym.typeComment.append(comment);
        }
    }
    
    sp<AaptSymbols> addNestedSymbol(const String8& name, const SourcePos& pos) {
        if (!check_valid_symbol_name(name, pos, "nested symbol")) {
            return NULL;
        }
        
        sp<AaptSymbols> sym = mNestedSymbols.valueFor(name);
        if (sym == NULL) {
            sym = new AaptSymbols();
            mNestedSymbols.add(name, sym);
        }

        return sym;
    }

    const KeyedVector<String8, AaptSymbolEntry>& getSymbols() const
        { return mSymbols; }
    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getNestedSymbols() const
        { return mNestedSymbols; }

    const String16& getComment(const String8& name) const
        { return get_symbol(name).comment; }
    const String16& getTypeComment(const String8& name) const
        { return get_symbol(name).typeComment; }

private:
    bool check_valid_symbol_name(const String8& symbol, const SourcePos& pos, const char* label) {
        if (valid_symbol_name(symbol)) {
            return true;
        }
        pos.error("invalid %s: '%s'\n", label, symbol.string());
        return false;
    }
    AaptSymbolEntry& edit_symbol(const String8& symbol, const SourcePos* pos) {
        ssize_t i = mSymbols.indexOfKey(symbol);
        if (i < 0) {
            i = mSymbols.add(symbol, AaptSymbolEntry(symbol));
        }
        AaptSymbolEntry& sym = mSymbols.editValueAt(i);
        if (pos != NULL && sym.sourcePos.line < 0) {
            sym.sourcePos = *pos;
        }
        return sym;
    }
    const AaptSymbolEntry& get_symbol(const String8& symbol) const {
        ssize_t i = mSymbols.indexOfKey(symbol);
        if (i >= 0) {
            return mSymbols.valueAt(i);
        }
        return mDefSymbol;
    }

    KeyedVector<String8, AaptSymbolEntry>           mSymbols;
    DefaultKeyedVector<String8, sp<AaptSymbols> >   mNestedSymbols;
    AaptSymbolEntry                                 mDefSymbol;
};

class ResourceTypeSet : public RefBase,
                        public KeyedVector<String8,sp<AaptGroup> >
{
public:
    ResourceTypeSet();
};


/**
 * Asset hierarchy being operated on.
 */
class AaptAssets : public AaptDir
{
public:
    AaptAssets() : AaptDir(String8(), String8()), mHaveIncludedAssets(false), mRes(NULL) { }
    virtual ~AaptAssets() { delete mRes; }

    const String8& getPackage() const { return mPackage; }
    void setPackage(const String8& package) { mPackage = package; mSymbolsPrivatePackage = package; }

    const SortedVector<AaptGroupEntry>& getGroupEntries() const { return mGroupEntries; }

    sp<AaptFile> addFile(const String8& filePath,
                         const AaptGroupEntry& entry,
                         const String8& srcDir,
                         sp<AaptGroup>* outGroup,
                         const String8& resType);

    void addResource(const String8& leafName,
                     const String8& path,
                     const sp<AaptFile>& file,
                     const String8& resType);

    void addGroupEntry(const AaptGroupEntry& entry) { mGroupEntries.add(entry); }
    
    ssize_t slurpFromArgs(Bundle* bundle);

    virtual ssize_t slurpFullTree(Bundle* bundle,
                                  const String8& srcDir,
                                  const AaptGroupEntry& kind,
                                  const String8& resType);

    ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir);
    ssize_t slurpResourceZip(Bundle* bundle, const char* filename);

    sp<AaptSymbols> getSymbolsFor(const String8& name);

    const DefaultKeyedVector<String8, sp<AaptSymbols> >& getSymbols() const { return mSymbols; }

    String8 getSymbolsPrivatePackage() const { return mSymbolsPrivatePackage; }
    void setSymbolsPrivatePackage(const String8& pkg) { mSymbolsPrivatePackage = pkg; }
    
    status_t buildIncludedResources(Bundle* bundle);
    status_t addIncludedResources(const sp<AaptFile>& file);
    const ResTable& getIncludedResources() const;

    void print() const;

    inline const Vector<sp<AaptDir> >& resDirs() { return mDirs; }
    sp<AaptDir> resDir(const String8& name);

    inline sp<AaptAssets> getOverlay() { return mOverlay; }
    inline void setOverlay(sp<AaptAssets>& overlay) { mOverlay = overlay; }
    
    inline KeyedVector<String8, sp<ResourceTypeSet> >* getResources() { return mRes; }
    inline void 
        setResources(KeyedVector<String8, sp<ResourceTypeSet> >* res) { delete mRes; mRes = res; }

private:
    String8 mPackage;
    SortedVector<AaptGroupEntry> mGroupEntries;
    DefaultKeyedVector<String8, sp<AaptSymbols> > mSymbols;
    String8 mSymbolsPrivatePackage;

    Vector<sp<AaptDir> > mDirs;

    bool mHaveIncludedAssets;
    AssetManager mIncludedAssets;

    sp<AaptAssets> mOverlay;
    KeyedVector<String8, sp<ResourceTypeSet> >* mRes;
};

#endif // __AAPT_ASSETS_H

