#include "idmap.h"

#include <UniquePtr.h>
#include <androidfw/AssetManager.h>
#include <androidfw/ResourceTypes.h>
#include <androidfw/ZipFileRO.h>
#include <utils/String8.h>

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

using namespace android;

namespace {
    int get_zip_entry_crc(const char *zip_path, const char *entry_name, uint32_t *crc)
    {
        UniquePtr<ZipFileRO> zip(ZipFileRO::open(zip_path));
        if (zip.get() == NULL) {
            return -1;
        }
        ZipEntryRO entry = zip->findEntryByName(entry_name);
        if (entry == NULL) {
            return -1;
        }
        if (!zip->getEntryInfo(entry, NULL, NULL, NULL, NULL, NULL, (long*)crc)) {
            return -1;
        }
        zip->releaseEntry(entry);
        return 0;
    }

    int open_idmap(const char *path)
    {
        int fd = TEMP_FAILURE_RETRY(open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644));
        if (fd == -1) {
            ALOGD("error: open %s: %s\n", path, strerror(errno));
            goto fail;
        }
        if (fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
            ALOGD("error: fchmod %s: %s\n", path, strerror(errno));
            goto fail;
        }
        if (TEMP_FAILURE_RETRY(flock(fd, LOCK_EX | LOCK_NB)) != 0) {
            ALOGD("error: flock %s: %s\n", path, strerror(errno));
            goto fail;
        }

        return fd;
fail:
        if (fd != -1) {
            close(fd);
            unlink(path);
        }
        return -1;
    }

    int write_idmap(int fd, const uint32_t *data, size_t size)
    {
        if (lseek(fd, SEEK_SET, 0) < 0) {
            return -1;
        }
        size_t bytesLeft = size;
        while (bytesLeft > 0) {
            ssize_t w = TEMP_FAILURE_RETRY(write(fd, data + size - bytesLeft, bytesLeft));
            if (w < 0) {
                fprintf(stderr, "error: write: %s\n", strerror(errno));
                return -1;
            }
            bytesLeft -= w;
        }
        return 0;
    }

    bool is_idmap_stale_fd(const char *target_apk_path, const char *overlay_apk_path, int idmap_fd)
    {
        static const size_t N = ResTable::IDMAP_HEADER_SIZE_BYTES;
        struct stat st;
        if (fstat(idmap_fd, &st) == -1) {
            return true;
        }
        if (st.st_size < N) {
            // file is empty or corrupt
            return true;
        }

        char buf[N];
        ssize_t bytesLeft = N;
        if (lseek(idmap_fd, SEEK_SET, 0) < 0) {
            return true;
        }
        for (;;) {
            ssize_t r = TEMP_FAILURE_RETRY(read(idmap_fd, buf + N - bytesLeft, bytesLeft));
            if (r < 0) {
                return true;
            }
            bytesLeft -= r;
            if (bytesLeft == 0) {
                break;
            }
            if (r == 0) {
                // "shouldn't happen"
                return true;
            }
        }

        uint32_t cached_target_crc, cached_overlay_crc;
        String8 cached_target_path, cached_overlay_path;
        if (!ResTable::getIdmapInfo(buf, N, NULL, &cached_target_crc, &cached_overlay_crc,
                    &cached_target_path, &cached_overlay_path)) {
            return true;
        }

        if (cached_target_path != target_apk_path) {
            return true;
        }
        if (cached_overlay_path != overlay_apk_path) {
            return true;
        }

        uint32_t actual_target_crc, actual_overlay_crc;
        if (get_zip_entry_crc(target_apk_path, AssetManager::RESOURCES_FILENAME,
				&actual_target_crc) == -1) {
            return true;
        }
        if (get_zip_entry_crc(overlay_apk_path, AssetManager::RESOURCES_FILENAME,
				&actual_overlay_crc) == -1) {
            return true;
        }

        return cached_target_crc != actual_target_crc || cached_overlay_crc != actual_overlay_crc;
    }

    bool is_idmap_stale_path(const char *target_apk_path, const char *overlay_apk_path,
            const char *idmap_path)
    {
        struct stat st;
        if (stat(idmap_path, &st) == -1) {
            // non-existing idmap is always stale; on other errors, abort idmap generation
            return errno == ENOENT;
        }

        int idmap_fd = TEMP_FAILURE_RETRY(open(idmap_path, O_RDONLY));
        if (idmap_fd == -1) {
            return false;
        }
        bool is_stale = is_idmap_stale_fd(target_apk_path, overlay_apk_path, idmap_fd);
        close(idmap_fd);
        return is_stale;
    }

    int create_idmap(const char *target_apk_path, const char *overlay_apk_path,
            uint32_t **data, size_t *size)
    {
        uint32_t target_crc, overlay_crc;
        if (get_zip_entry_crc(target_apk_path, AssetManager::RESOURCES_FILENAME,
				&target_crc) == -1) {
            return -1;
        }
        if (get_zip_entry_crc(overlay_apk_path, AssetManager::RESOURCES_FILENAME,
				&overlay_crc) == -1) {
            return -1;
        }

        AssetManager am;
        bool b = am.createIdmap(target_apk_path, overlay_apk_path, target_crc, overlay_crc,
                data, size);
        return b ? 0 : -1;
    }

    int create_and_write_idmap(const char *target_apk_path, const char *overlay_apk_path,
            int fd, bool check_if_stale)
    {
        if (check_if_stale) {
            if (!is_idmap_stale_fd(target_apk_path, overlay_apk_path, fd)) {
                // already up to date -- nothing to do
                return 0;
            }
        }

        uint32_t *data = NULL;
        size_t size;

        if (create_idmap(target_apk_path, overlay_apk_path, &data, &size) == -1) {
            return -1;
        }

        if (write_idmap(fd, data, size) == -1) {
            free(data);
            return -1;
        }

        free(data);
        return 0;
    }
}

int idmap_create_path(const char *target_apk_path, const char *overlay_apk_path,
        const char *idmap_path)
{
    if (!is_idmap_stale_path(target_apk_path, overlay_apk_path, idmap_path)) {
        // already up to date -- nothing to do
        return EXIT_SUCCESS;
    }

    int fd = open_idmap(idmap_path);
    if (fd == -1) {
        return EXIT_FAILURE;
    }

    int r = create_and_write_idmap(target_apk_path, overlay_apk_path, fd, false);
    close(fd);
    if (r != 0) {
        unlink(idmap_path);
    }
    return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, int fd)
{
    return create_and_write_idmap(target_apk_path, overlay_apk_path, fd, true) == 0 ?
        EXIT_SUCCESS : EXIT_FAILURE;
}
