#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/file.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, 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 -= static_cast<size_t>(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 < static_cast<off_t>(N)) {
            // file is empty or corrupt
            return true;
        }

        char buf[N];
        size_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 -= static_cast<size_t>(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;
}
