#include <dirent.h>
#include <sys/stat.h>

#include "idmap.h"

#include <UniquePtr.h>
#include <androidfw/ResourceTypes.h>
#include <androidfw/StreamingZipInflater.h>
#include <androidfw/ZipFileRO.h>
#include <private/android_filesystem_config.h> // for AID_SYSTEM
#include <utils/SortedVector.h>
#include <utils/String16.h>
#include <utils/String8.h>

#define NO_OVERLAY_TAG (-1000)

using namespace android;

namespace {
    struct Overlay {
        Overlay() {}
        Overlay(const String8& a, const String8& i, int p) :
            apk_path(a), idmap_path(i), priority(p) {}

        bool operator<(Overlay const& rhs) const
        {
            // Note: order is reversed by design
            return rhs.priority < priority;
        }

        String8 apk_path;
        String8 idmap_path;
        int priority;
    };

    bool writePackagesList(const char *filename, const SortedVector<Overlay>& overlayVector)
    {
        FILE* fout = fopen(filename, "w");
        if (fout == NULL) {
            return false;
        }

        for (size_t i = 0; i < overlayVector.size(); ++i) {
            const Overlay& overlay = overlayVector[i];
            fprintf(fout, "%s %s\n", overlay.apk_path.string(), overlay.idmap_path.string());
        }

        fclose(fout);

        // Make file world readable since Zygote (running as root) will read
        // it when creating the initial AssetManger object
        const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // 0644
        if (chmod(filename, mode) == -1) {
            unlink(filename);
            return false;
        }

        return true;
    }

    String8 flatten_path(const char *path)
    {
        String16 tmp(path);
        tmp.replaceAll('/', '@');
        return String8(tmp);
    }

    int parse_overlay_tag(const ResXMLTree& parser, const char *target_package_name)
    {
        const size_t N = parser.getAttributeCount();
        String16 target;
        int priority = -1;
        for (size_t i = 0; i < N; ++i) {
            size_t len;
            String16 key(parser.getAttributeName(i, &len));
            if (key == String16("targetPackage")) {
                const char16_t *p = parser.getAttributeStringValue(i, &len);
                if (p != NULL) {
                    target = String16(p, len);
                }
            } else if (key == String16("priority")) {
                Res_value v;
                if (parser.getAttributeValue(i, &v) == sizeof(Res_value)) {
                    priority = v.data;
                    if (priority < 0 || priority > 9999) {
                        return -1;
                    }
                }
            }
        }
        if (target == String16(target_package_name)) {
            return priority;
        }
        return NO_OVERLAY_TAG;
    }

    int parse_manifest(const void *data, size_t size, const char *target_package_name)
    {
        ResXMLTree parser;
        parser.setTo(data, size);
        if (parser.getError() != NO_ERROR) {
            ALOGD("%s failed to init xml parser, error=0x%08x\n", __FUNCTION__, parser.getError());
            return -1;
        }

        ResXMLParser::event_code_t type;
        do {
            type = parser.next();
            if (type == ResXMLParser::START_TAG) {
                size_t len;
                String16 tag(parser.getElementName(&len));
                if (tag == String16("overlay")) {
                    return parse_overlay_tag(parser, target_package_name);
                }
            }
        } while (type != ResXMLParser::BAD_DOCUMENT && type != ResXMLParser::END_DOCUMENT);

        return NO_OVERLAY_TAG;
    }

    int parse_apk(const char *path, const char *target_package_name)
    {
        UniquePtr<ZipFileRO> zip(ZipFileRO::open(path));
        if (zip.get() == NULL) {
            ALOGW("%s: failed to open zip %s\n", __FUNCTION__, path);
            return -1;
        }
        ZipEntryRO entry;
        if ((entry = zip->findEntryByName("AndroidManifest.xml")) == NULL) {
            ALOGW("%s: failed to find entry AndroidManifest.xml\n", __FUNCTION__);
            return -1;
        }
        size_t uncompLen = 0;
        int method;
        if (!zip->getEntryInfo(entry, &method, &uncompLen, NULL, NULL, NULL, NULL)) {
            ALOGW("%s: failed to read entry info\n", __FUNCTION__);
            return -1;
        }
        if (method != ZipFileRO::kCompressDeflated) {
            ALOGW("%s: cannot handle zip compression method %d\n", __FUNCTION__, method);
            return -1;
        }
        FileMap *dataMap = zip->createEntryFileMap(entry);
        if (dataMap == NULL) {
            ALOGW("%s: failed to create FileMap\n", __FUNCTION__);
            return -1;
        }
        char *buf = new char[uncompLen];
        if (NULL == buf) {
            ALOGW("%s: failed to allocate %zd byte\n", __FUNCTION__, uncompLen);
            delete dataMap;
            return -1;
        }
        StreamingZipInflater inflater(dataMap, uncompLen);
        if (inflater.read(buf, uncompLen) < 0) {
            ALOGW("%s: failed to inflate %zd byte\n", __FUNCTION__, uncompLen);
            delete[] buf;
            delete dataMap;
            return -1;
        }

        int priority = parse_manifest(buf, uncompLen, target_package_name);
        delete[] buf;
        delete dataMap;
        return priority;
    }
}

int idmap_scan(const char *overlay_dir, const char *target_package_name,
        const char *target_apk_path, const char *idmap_dir)
{
    String8 filename = String8(idmap_dir);
    filename.appendPath("overlays.list");
    if (unlink(filename.string()) != 0 && errno != ENOENT) {
        return EXIT_FAILURE;
    }

    DIR *dir = opendir(overlay_dir);
    if (dir == NULL) {
        return EXIT_FAILURE;
    }

    SortedVector<Overlay> overlayVector;
    struct dirent *dirent;
    while ((dirent = readdir(dir)) != NULL) {
        struct stat st;
        char overlay_apk_path[PATH_MAX + 1];
        snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
        if (stat(overlay_apk_path, &st) < 0) {
            continue;
        }
        if (!S_ISREG(st.st_mode)) {
            continue;
        }

        int priority = parse_apk(overlay_apk_path, target_package_name);
        if (priority < 0) {
            continue;
        }

        String8 idmap_path(idmap_dir);
        idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
        idmap_path.append("@idmap");

        if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
            ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
                    target_apk_path, overlay_apk_path, idmap_path.string());
            continue;
        }

        Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
        overlayVector.add(overlay);
    }

    closedir(dir);

    if (!writePackagesList(filename.string(), overlayVector)) {
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
