/*
 * Copyright (C) 2019 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 <libfiemap_writer/split_fiemap_writer.h>

#include <fcntl.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <vector>

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>

#include "utility.h"

namespace android {
namespace fiemap_writer {

using android::base::unique_fd;

// We use a four-digit suffix at the end of filenames.
static const size_t kMaxFilePieces = 500;

std::unique_ptr<SplitFiemap> SplitFiemap::Create(const std::string& file_path, uint64_t file_size,
                                                 uint64_t max_piece_size,
                                                 ProgressCallback progress) {
    if (!file_size) {
        LOG(ERROR) << "Cannot create a fiemap for a 0-length file: " << file_path;
        return nullptr;
    }

    if (!max_piece_size) {
        max_piece_size = DetermineMaximumFileSize(file_path);
        if (!max_piece_size) {
            LOG(ERROR) << "Could not determine maximum file size for " << file_path;
            return nullptr;
        }
    }

    // Call |progress| only when the total percentage would significantly change.
    int permille = -1;
    uint64_t total_bytes_written = 0;
    auto on_progress = [&](uint64_t written, uint64_t) -> bool {
        uint64_t actual_written = total_bytes_written + written;
        int new_permille = (actual_written * 1000) / file_size;
        if (new_permille != permille && actual_written < file_size) {
            if (progress && !progress(actual_written, file_size)) {
                return false;
            }
            permille = new_permille;
        }
        return true;
    };

    std::unique_ptr<SplitFiemap> out(new SplitFiemap());
    out->creating_ = true;
    out->list_file_ = file_path;

    // Create the split files.
    uint64_t remaining_bytes = file_size;
    while (remaining_bytes) {
        if (out->files_.size() >= kMaxFilePieces) {
            LOG(ERROR) << "Requested size " << file_size << " created too many split files";
            return nullptr;
        }
        std::string chunk_path =
                android::base::StringPrintf("%s.%04d", file_path.c_str(), (int)out->files_.size());
        uint64_t chunk_size = std::min(max_piece_size, remaining_bytes);
        auto writer = FiemapWriter::Open(chunk_path, chunk_size, true, on_progress);
        if (!writer) {
            return nullptr;
        }

        // To make sure the alignment doesn't create too much inconsistency, we
        // account the *actual* size, not the requested size.
        total_bytes_written += writer->size();
        // writer->size() is block size aligned and could be bigger than remaining_bytes
        // If remaining_bytes is bigger, set remaining_bytes to 0 to avoid underflow error.
        remaining_bytes = remaining_bytes > writer->size() ? (remaining_bytes - writer->size()) : 0;
        out->AddFile(std::move(writer));
    }

    // Create the split file list.
    unique_fd fd(open(out->list_file_.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0660));
    if (fd < 0) {
        PLOG(ERROR) << "Failed to open " << file_path;
        return nullptr;
    }

    for (const auto& writer : out->files_) {
        std::string line = android::base::Basename(writer->file_path()) + "\n";
        if (!android::base::WriteFully(fd, line.data(), line.size())) {
            PLOG(ERROR) << "Write failed " << file_path;
            return nullptr;
        }
    }

    // Unset this bit, so we don't unlink on destruction.
    out->creating_ = false;
    return out;
}

std::unique_ptr<SplitFiemap> SplitFiemap::Open(const std::string& file_path) {
    std::vector<std::string> files;
    if (!GetSplitFileList(file_path, &files)) {
        return nullptr;
    }

    std::unique_ptr<SplitFiemap> out(new SplitFiemap());
    out->list_file_ = file_path;

    for (const auto& file : files) {
        auto writer = FiemapWriter::Open(file, 0, false);
        if (!writer) {
            // Error was logged in Open().
            return nullptr;
        }
        out->AddFile(std::move(writer));
    }
    return out;
}

bool SplitFiemap::GetSplitFileList(const std::string& file_path, std::vector<std::string>* list) {
    // This is not the most efficient thing, but it is simple and recovering
    // the fiemap/fibmap is much more expensive.
    std::string contents;
    if (!android::base::ReadFileToString(file_path, &contents, true)) {
        PLOG(ERROR) << "Error reading file: " << file_path;
        return false;
    }

    std::vector<std::string> names = android::base::Split(contents, "\n");
    std::string dir = android::base::Dirname(file_path);
    for (const auto& name : names) {
        if (!name.empty()) {
            list->emplace_back(dir + "/" + name);
        }
    }
    return true;
}

bool SplitFiemap::RemoveSplitFiles(const std::string& file_path, std::string* message) {
    // Early exit if this does not exist, and do not report an error.
    if (access(file_path.c_str(), F_OK) && errno == ENOENT) {
        return true;
    }

    bool ok = true;
    std::vector<std::string> files;
    if (GetSplitFileList(file_path, &files)) {
        for (const auto& file : files) {
            ok &= android::base::RemoveFileIfExists(file, message);
        }
    }
    ok &= android::base::RemoveFileIfExists(file_path, message);
    return ok;
}

bool SplitFiemap::HasPinnedExtents() const {
    for (const auto& file : files_) {
        if (!FiemapWriter::HasPinnedExtents(file->file_path())) {
            return false;
        }
    }
    return true;
}

const std::vector<struct fiemap_extent>& SplitFiemap::extents() {
    if (extents_.empty()) {
        for (const auto& file : files_) {
            const auto& extents = file->extents();
            extents_.insert(extents_.end(), extents.begin(), extents.end());
        }
    }
    return extents_;
}

bool SplitFiemap::Write(const void* data, uint64_t bytes) {
    // Open the current file.
    FiemapWriter* file = files_[cursor_index_].get();

    const uint8_t* data_ptr = reinterpret_cast<const uint8_t*>(data);
    uint64_t bytes_remaining = bytes;
    while (bytes_remaining) {
        // How many bytes can we write into the current file?
        uint64_t file_bytes_left = file->size() - cursor_file_pos_;
        if (!file_bytes_left) {
            if (cursor_index_ == files_.size() - 1) {
                LOG(ERROR) << "write past end of file requested";
                return false;
            }

            // No space left in the current file, but we have more files to
            // use, so prep the next one.
            cursor_fd_ = {};
            cursor_file_pos_ = 0;
            file = files_[++cursor_index_].get();
            file_bytes_left = file->size();
        }

        // Open the current file if it's not open.
        if (cursor_fd_ < 0) {
            cursor_fd_.reset(open(file->file_path().c_str(), O_CLOEXEC | O_WRONLY));
            if (cursor_fd_ < 0) {
                PLOG(ERROR) << "open failed: " << file->file_path();
                return false;
            }
            CHECK(cursor_file_pos_ == 0);
        }

        if (!FiemapWriter::HasPinnedExtents(file->file_path())) {
            LOG(ERROR) << "file is no longer pinned: " << file->file_path();
            return false;
        }

        uint64_t bytes_to_write = std::min(file_bytes_left, bytes_remaining);
        if (!android::base::WriteFully(cursor_fd_, data_ptr, bytes_to_write)) {
            PLOG(ERROR) << "write failed: " << file->file_path();
            return false;
        }
        data_ptr += bytes_to_write;
        bytes_remaining -= bytes_to_write;
        cursor_file_pos_ += bytes_to_write;
    }

    // If we've reached the end of the current file, close it for sanity.
    if (cursor_file_pos_ == file->size()) {
        cursor_fd_ = {};
    }
    return true;
}

bool SplitFiemap::Flush() {
    for (const auto& file : files_) {
        unique_fd fd(open(file->file_path().c_str(), O_RDONLY | O_CLOEXEC));
        if (fd < 0) {
            PLOG(ERROR) << "open failed: " << file->file_path();
            return false;
        }
        if (fsync(fd)) {
            PLOG(ERROR) << "fsync failed: " << file->file_path();
            return false;
        }
    }
    return true;
}

SplitFiemap::~SplitFiemap() {
    if (!creating_) {
        return;
    }

    // We failed to finish creating, so unlink everything.
    unlink(list_file_.c_str());
    for (auto&& file : files_) {
        std::string path = file->file_path();
        file = nullptr;

        unlink(path.c_str());
    }
}

void SplitFiemap::AddFile(FiemapUniquePtr&& file) {
    total_size_ += file->size();
    files_.emplace_back(std::move(file));
}

uint32_t SplitFiemap::block_size() const {
    return files_[0]->block_size();
}

const std::string& SplitFiemap::bdev_path() const {
    return files_[0]->bdev_path();
}

}  // namespace fiemap_writer
}  // namespace android
