/*
 * Copyright (C) 2016 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.
 */

#include "ZipUtil.h"

#include <errno.h>
#include <fcntl.h>
#include <utime.h>

#include <string>

#include <android-base/logging.h>
#include <android-base/unique_fd.h>
#include <selinux/label.h>
#include <selinux/selinux.h>
#include <ziparchive/zip_archive.h>

#include "otautil/dirutil.h"

static constexpr mode_t UNZIP_DIRMODE = 0755;
static constexpr mode_t UNZIP_FILEMODE = 0644;

bool ExtractPackageRecursive(ZipArchiveHandle zip, const std::string& zip_path,
                             const std::string& dest_path, const struct utimbuf* timestamp,
                             struct selabel_handle* sehnd) {
    if (!zip_path.empty() && zip_path[0] == '/') {
        LOG(ERROR) << "ExtractPackageRecursive(): zip_path must be a relative path " << zip_path;
        return false;
    }
    if (dest_path.empty() || dest_path[0] != '/') {
        LOG(ERROR) << "ExtractPackageRecursive(): dest_path must be an absolute path " << dest_path;
        return false;
    }

    void* cookie;
    std::string target_dir(dest_path);
    if (dest_path.back() != '/') {
        target_dir += '/';
    }
    std::string prefix_path(zip_path);
    if (!zip_path.empty() && zip_path.back() != '/') {
        prefix_path += '/';
    }
    const std::string zip_prefix(prefix_path.c_str());

    int ret = StartIteration(zip, &cookie, zip_prefix, nullptr);
    if (ret != 0) {
        LOG(ERROR) << "failed to start iterating zip entries.";
        return false;
    }

    std::unique_ptr<void, decltype(&EndIteration)> guard(cookie, EndIteration);
    ZipEntry entry;
    std::string name;
    int extractCount = 0;
    while (Next(cookie, &entry, &name) == 0) {
        std::string entry_name(name.c_str(), name.c_str() + name.size());
        CHECK_LE(prefix_path.size(), entry_name.size());
        std::string path = target_dir + entry_name.substr(prefix_path.size());
        // Skip dir.
        if (path.back() == '/') {
            continue;
        }
        //TODO(b/31917448) handle the symlink.

        if (dirCreateHierarchy(path.c_str(), UNZIP_DIRMODE, timestamp, true, sehnd) != 0) {
            LOG(ERROR) << "failed to create dir for " << path;
            return false;
        }

        char *secontext = NULL;
        if (sehnd) {
            selabel_lookup(sehnd, &secontext, path.c_str(), UNZIP_FILEMODE);
            setfscreatecon(secontext);
        }
        android::base::unique_fd fd(open(path.c_str(), O_CREAT|O_WRONLY|O_TRUNC, UNZIP_FILEMODE));
        if (fd == -1) {
            PLOG(ERROR) << "Can't create target file \"" << path << "\"";
            return false;
        }
        if (secontext) {
            freecon(secontext);
            setfscreatecon(NULL);
        }

        int err = ExtractEntryToFile(zip, &entry, fd);
        if (err != 0) {
            LOG(ERROR) << "Error extracting \"" << path << "\" : " << ErrorCodeString(err);
            return false;
        }

        if (fsync(fd) != 0) {
            PLOG(ERROR) << "Error syncing file descriptor when extracting \"" << path << "\"";
            return false;
        }

        if (timestamp != nullptr && utime(path.c_str(), timestamp)) {
            PLOG(ERROR) << "Error touching \"" << path << "\"";
            return false;
        }

        LOG(INFO) << "Extracted file \"" << path << "\"";
        ++extractCount;
    }

    LOG(INFO) << "Extracted " << extractCount << " file(s)";
    return true;
}
