// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#define _XOPEN_SOURCE

#include <errno.h>
#include <limits.h>
#include <string.h>

#include <fbl/algorithm.h>
#include <minfs/fsck.h>
#include <minfs/host.h>
#include <minfs/minfs.h>
#include <minfs/transaction-limits.h>

#include <utility>

#include "minfs.h"

char kDot[2] = ".";
char kDotDot[3] = "..";

namespace {
template <class T> uint32_t ToU32(T in) {
    if (in > std::numeric_limits<uint32_t>::max()) {
        fprintf(stderr, "out of range %" PRIuMAX "\n",
                static_cast<uintmax_t>(in));
        exit(-1);
    }
    return static_cast<uint32_t>(in);
}
} // namespace

// Returns the string version of |mode|.
static const char* GetModeString(uint32_t mode) {
    switch (mode & S_IFMT) {
    case S_IFREG:
        return "-";
    case S_IFCHR:
        return "c";
    case S_IFBLK:
        return "b";
    case S_IFDIR:
        return "d";
    default:
        return "?";
    }
}

// Adds PATH_PREFIX to path if it isn't there
void GetHostPath(const char* path, char* out) {
    out[0] = 0;
    int remaining = PATH_MAX;

    if (strncmp(path, PATH_PREFIX, PREFIX_SIZE)) {
        strncat(out, PATH_PREFIX, remaining);
        remaining -= strlen(PATH_PREFIX);
    }

    strncat(out, path, remaining);
}

// Checks if the given |path| is a directory, and return the answer in |*result|.
zx_status_t IsDirectory(const char* path, bool* result) {
    struct stat s;
    bool host = host_path(path);

    if (host) {
        if (stat(path, &s) < 0) {
            return ZX_ERR_IO;
        }
    } else {
        if (!emu_is_mounted()) {
            fprintf(stderr, "Cannot check directory of unmounted minfs partition\n");
            return ZX_ERR_INTERNAL;
        }

        if (emu_stat(path, &s) < 0) {
            return ZX_ERR_IO;
        }
    }

    if (S_ISDIR(s.st_mode)) {
        *result = true;
    } else {
        *result = false;
    }
    return ZX_OK;
}

// Copies a file to minfs from the host, or vice versa.
zx_status_t CopyFile(const char* src_path, const char* dst_path) {
    FileWrapper src;
    FileWrapper dst;

    if (FileWrapper::Open(src_path, O_RDONLY, 0, &src) < 0) {
        fprintf(stderr, "error: cannot open file '%s'\n", src_path);
        return ZX_ERR_IO;
    }

    if (FileWrapper::Open(dst_path, O_WRONLY | O_CREAT | O_EXCL, 0644, &dst) < 0) {
        fprintf(stderr, "error: cannot open file '%s'\n", dst_path);
        return ZX_ERR_IO;
    }

    char buffer[256 * 1024];
    ssize_t r;
    for (;;) {
        if ((r = src.Read(buffer, sizeof(buffer))) < 0) {
            fprintf(stderr, "error: reading from '%s'\n", src_path);
            break;
        } else if (r == 0) {
            break;
        }
        void* ptr = buffer;
        ssize_t len = r;
        while (len > 0) {
            if ((r = dst.Write(ptr, len)) < 0) {
                fprintf(stderr, "error: writing to '%s'\n", dst_path);
                goto done;
            }
            ptr = (void*)((uintptr_t)ptr + r);
            len -= r;
        }
    }
done:
    return r == 0 ? ZX_OK : ZX_ERR_IO;
}

// Attempts to make the directory at |path|.
// Returns a positive result if creation was successful or the specified directory already exists.
zx_status_t MakeDirectory(const char* path) {
    if (DirWrapper::Make(path, 0777) && errno != EEXIST) {
        fprintf(stderr, "minfs: could not create directory %s: %s\n", path, strerror(errno));
        return ZX_ERR_IO;
    }

    return ZX_OK;
}

zx_status_t MinfsCreator::Usage() {
    zx_status_t status = FsCreator::Usage();

    // Additional information about manifest format.
    fprintf(stderr, "\nThe format of the manifest must be as follows:\n");
    fprintf(stderr, "\t'dst/path=src/path'\n");
    fprintf(stderr, "with one dst/src pair on each line.\n");

    fprintf(stderr, "\nPrefix all minfs paths with '::' "
                    "(unless they are included in a manifest).\n");
    return status;
}

bool MinfsCreator::IsCommandValid(Command command) {
    switch (command) {
    case Command::kMkfs:
    case Command::kFsck:
    case Command::kUsedDataSize:
    case Command::kUsedInodes:
    case Command::kUsedSize:
    case Command::kLs:
    case Command::kCp:
    case Command::kManifest:
    case Command::kMkdir:
    case Command::kAdd:
        return true;
    default:
        return false;
    }
}

bool MinfsCreator::IsOptionValid(Option option) {
    switch (option) {
    case Option::kDepfile:
    case Option::kReadonly:
    case Option::kOffset:
    case Option::kLength:
    case Option::kHelp:
        return true;
    default:
        return false;
    }
}

bool MinfsCreator::IsArgumentValid(Argument argument) {
    switch (argument) {
    case Argument::kManifest:
        return true;
    default:
        return false;
    }
}

zx_status_t MinfsCreator::ProcessManifestLine(FILE* manifest, const char* dir_path) {
    char src[PATH_MAX];
    src[0] = '\0';
    char dst[PATH_MAX];
    dst[0] = '\0';

    zx_status_t status;
    if ((status = ParseManifestLine(manifest, dir_path, &src[0], &dst[0])) != ZX_OK) {
        return status;
    }

    if (!strlen(src) || !strlen(dst)) {
        fprintf(stderr, "Manifest line must specify source and destination files\n");
        return ZX_ERR_INVALID_ARGS;
    }

    bool dir;
    if ((status = IsDirectory(src, &dir)) != ZX_OK) {
        return status;
    }

    if (dir) {
        fprintf(stderr, "Manifest cannot specify directory as source\n");
        return ZX_ERR_INVALID_ARGS;
    }

    // Make dst into minfs path.
    char emu_dst[PATH_MAX];
    GetHostPath(dst, emu_dst);

    // Process parent directories.
    if ((status = ProcessParentDirectories(emu_dst)) != ZX_OK) {
        return status;
    }

    // Copy src to dst.
    return ProcessFile(src, emu_dst);
}

zx_status_t MinfsCreator::ProcessCustom(int argc, char** argv, uint8_t* processed) {
    uint8_t required_args = 0;

    switch (GetCommand()) {
    case Command::kLs:
        __FALLTHROUGH;
    case Command::kMkdir: {
        required_args = 1;
        if (argc != required_args) {
            return ZX_ERR_INVALID_ARGS;
        }

        // A non-host path is required here since the ls and mkdir commands must be run on minfs.
        if (host_path(argv[0])) {
            fprintf(stderr, "Must specify path with prefix '::'");
            return ZX_ERR_INVALID_ARGS;
        }

        // ls and mkdir can only be run on one path at a time.
        if (!dir_list_.is_empty()) {
            fprintf(stderr, "Too many paths specified\n");
            return ZX_ERR_INVALID_ARGS;
        }

        if (GetCommand() == Command::kLs) {
            dir_list_.push_back(argv[0]);
            return ZX_OK;
        }

        zx_status_t status;
        if ((status = ProcessParentDirectories(argv[0])) != ZX_OK) {
            return status;
        }

        if ((status = ProcessDirectory(argv[0])) != ZX_OK) {
            return status;
        }
        break;
    }
    case Command::kCp: {
        required_args = 2;
        if (argc != required_args) {
            return ZX_ERR_INVALID_ARGS;
        }

        // If our source file is located within minfs, we need to mount the minfs image so that we
        // can process any child files/directories.
        zx_status_t status;
        if (!host_path(argv[0]) && (status = MountMinfs()) != ZX_OK) {
            return status;
        }

        char src[PATH_MAX];
        char dst[PATH_MAX];
        strncpy(src, argv[0], PATH_MAX);
        strncpy(dst, argv[1], PATH_MAX);

        if ((status = ProcessParentDirectories(dst)) != ZX_OK) {
            return status;
        }

        if ((status = ProcessEntityAndChildren(src, dst)) != ZX_OK) {
            return status;
        }
        break;
    }
    case Command::kManifest: {
        required_args = 1;
        if (argc != required_args) {
            return ZX_ERR_INVALID_ARGS;
        }
        zx_status_t status;
        if ((status = ProcessManifest(argv[0])) != ZX_OK) {
            return status;
        }
        break;
    }
    default:
        fprintf(stderr, "Arguments not supported\n");
        return ZX_ERR_INVALID_ARGS;
    }

    *processed = required_args;
    return ZX_OK;
}

zx_status_t MinfsCreator::CalculateRequiredSize(off_t* out) {
    uint32_t dir_count =
        static_cast<uint32_t>(dir_list_.size() + 1); // dir_list_ + root

    // This is a rough estimate of how many directory data blocks will be needed.
    // This is not super robust and will not hold up if directories start requiring indirect blocks,
    // but for our current purposes it should be sufficient.
    uint32_t dir_blocks = ToU32(dir_count + (dir_bytes_ / minfs::kMinfsBlockSize));

    minfs::Superblock info;
    info.flags = 0;
    info.inode_count = minfs::kMinfsDefaultInodeCount;
    info.block_count = ToU32(data_blocks_ + dir_blocks);

    // Calculate number of blocks we will need for all minfs structures.
    uint32_t inode_bitmap_blocks = (info.inode_count + minfs::kMinfsBlockBits - 1)
                                   / minfs::kMinfsBlockBits;
    uint32_t block_bitmap_blocks = (info.block_count + minfs::kMinfsBlockBits - 1)
                                   / minfs::kMinfsBlockBits;
    uint32_t inode_table_blocks = (info.inode_count + minfs::kMinfsInodesPerBlock - 1)
                                  / minfs::kMinfsInodesPerBlock;

    info.ibm_block = 8;
    info.abm_block = info.ibm_block + fbl::round_up(inode_bitmap_blocks, 8u);
    info.ino_block = info.abm_block + fbl::round_up(block_bitmap_blocks, 8u);
    info.journal_start_block = info.ino_block + inode_table_blocks;
    minfs::TransactionLimits limits(info);
    info.dat_block = info.journal_start_block + limits.GetRecommendedJournalBlocks();

    *out = (info.dat_block + info.block_count) * minfs::kMinfsBlockSize;
    return ZX_OK;
}

zx_status_t MinfsCreator::Mkfs() {
    zx_status_t status;
    fbl::unique_ptr<minfs::Bcache> bc;

    // Create the bcache.
    if ((status = GenerateBcache(&bc)) != ZX_OK) {
        return status;
    }

    // Consume the bcache to mkfs.
    if ((status = minfs::Mkfs(std::move(bc))) != ZX_OK) {
        return status;
    }

    // Add any directories/files that have been pre-processed.
    if ((status = Add()) != ZX_OK) {
        fprintf(stderr, "Warning: Adding files on create failed - required size may have been "
                        "miscalculated\n");
    }

    return status;
}

zx_status_t MinfsCreator::Fsck() {
    zx_status_t status;
    fbl::unique_ptr<minfs::Bcache> bc;
    if ((status = GenerateBcache(&bc)) != ZX_OK) {
        return status;
    }
    return minfs::Fsck(std::move(bc));
}

zx_status_t MinfsCreator::UsedDataSize() {
    zx_status_t status;
    uint64_t size;
    fbl::unique_ptr<minfs::Bcache> bc;
    if ((status = GenerateBcache(&bc)) != ZX_OK) {
        return status;
    }
    if ((status = minfs::UsedDataSize(bc, &size)) != ZX_OK) {
        return status;
    }

    printf("%" PRIu64 "\n", size);
    return ZX_OK;
}

zx_status_t MinfsCreator::UsedInodes() {
    zx_status_t status;
    uint64_t used_inodes;
    fbl::unique_ptr<minfs::Bcache> bc;
    if ((status = GenerateBcache(&bc)) != ZX_OK) {
        return status;
    }
    if ((status = minfs::UsedInodes(bc, &used_inodes)) != ZX_OK) {
        return status;
    }

    printf("%" PRIu64 "\n", used_inodes);
    return ZX_OK;
}

zx_status_t MinfsCreator::UsedSize() {
    zx_status_t status;
    uint64_t size;
    fbl::unique_ptr<minfs::Bcache> bc;
    if ((status = GenerateBcache(&bc)) != ZX_OK) {
        return status;
    }
    if ((status = minfs::UsedSize(bc, &size)) != ZX_OK) {
        return status;
    }

    printf("%" PRIu64 "\n", size);
    return ZX_OK;
}

zx_status_t MinfsCreator::Add() {
    zx_status_t status;
    // Mount the minfs.
    if ((status = MountMinfs()) != ZX_OK) {
        return status;
    }

    // Make all directories.
    for (size_t n = 0; n < dir_list_.size(); n++) {
        if ((status = MakeDirectory(dir_list_[n].c_str())) != ZX_OK) {
            return status;
        }
    }

    // Copy all files.
    for (size_t n = 0; n < file_list_.size(); n++) {
        if ((status = AppendDepfile(file_list_[n].first.c_str())) != ZX_OK) {
            return status;
        }
        if ((status = CopyFile(file_list_[n].first.c_str(), file_list_[n].second.c_str())) != ZX_OK) {
            return status;
        }
    }

    return ZX_OK;
}

zx_status_t MinfsCreator::Ls() {
    if (!file_list_.is_empty() || dir_list_.size() != 1) {
        fprintf(stderr, "ls requires one argument\n");
        return Usage();
    }

    zx_status_t status;
    if ((status = MountMinfs()) != ZX_OK) {
        return status;
    }

    const char* path = dir_list_[0].c_str();
    if (strncmp(path, PATH_PREFIX, PREFIX_SIZE)) {
        fprintf(stderr, "error: ls can only operate minfs paths (must start with %s)\n",
                PATH_PREFIX);
        return ZX_ERR_INVALID_ARGS;
    }

    DIR* d = emu_opendir(path);
    if (!d) {
        return ZX_ERR_IO;
    }

    struct dirent* dir_entry;
    char tmp[2048];
    struct stat stats;
    while ((dir_entry = emu_readdir(d)) != nullptr) {
        if (strcmp(dir_entry->d_name, ".") && strcmp(dir_entry->d_name, "..")) {
            memset(&stats, 0, sizeof(struct stat));
            if ((strlen(dir_entry->d_name) + strlen(path) + 2) <= sizeof(tmp)) {
                snprintf(tmp, sizeof(tmp), "%s/%s", path, dir_entry->d_name);
                emu_stat(tmp, &stats);
            }
            fprintf(stdout, "%s %8jd %s\n", GetModeString(stats.st_mode),
                    static_cast<intmax_t>(stats.st_size), dir_entry->d_name);
        }
    }
    emu_closedir(d);
    return ZX_OK;
}

zx_status_t MinfsCreator::ProcessEntityAndChildren(char* src, char* dst) {
    bool dir;
    zx_status_t status;
    if ((status = IsDirectory(src, &dir)) != ZX_OK) {
        return status;
    }

    if (dir) {
        ProcessDirectory(dst);
    } else {
        return ProcessFile(src, dst);
    }

    DirWrapper current_dir;
    if (DirWrapper::Open(src, &current_dir)) {
        return ZX_ERR_IO;
    }

    size_t src_len = strlen(src);
    size_t dst_len = strlen(dst);
    struct dirent* dir_entry;
    while ((dir_entry = current_dir.ReadDir()) != nullptr) {
        if (!strcmp(dir_entry->d_name, ".") || !strcmp(dir_entry->d_name, "..")) {
            continue;
        }
        size_t name_len = strlen(dir_entry->d_name);
        if (src_len + name_len + 1 > PATH_MAX - 1 ||
            dst_len + name_len + 1 > PATH_MAX - 1) {
            fprintf(stderr, "Path size exceeds PATH_MAX\n");
            return ZX_ERR_INVALID_ARGS;
        }
        strncat(src, "/", 1);
        strncat(src, dir_entry->d_name, PATH_MAX - src_len - 2);
        strncat(dst, "/", 1);
        strncat(dst, dir_entry->d_name, PATH_MAX - dst_len - 2);

        zx_status_t status = ProcessEntityAndChildren(src, dst);
        if (status != ZX_OK) {
            return status;
        }

        src[src_len] = '\0';
        dst[dst_len] = '\0';
    }
    return 0;
}

zx_status_t MinfsCreator::ProcessParentDirectories(char* path) {
    // Create parent directories if they don't exist.
    char* slash = strchr(path, '/');
    while (slash != nullptr) {
        *slash = '\0';

        char emu_path[PATH_MAX];
        GetHostPath(path, emu_path);

        zx_status_t status;
        if ((status = ProcessDirectory(emu_path)) != ZX_OK) {
            return status;
        }

        *slash = '/';
        slash = strchr(slash + 1, '/');
    }

    return ZX_OK;
}

zx_status_t MinfsCreator::ProcessDirectory(char* path) {
    if (!strncmp(path, PATH_PREFIX, strlen(path))) {
        // If |path| is the minfs root directory ("::"), return without processing.
        return ZX_OK;
    }

    // Check to see if |path| has already been processed.
    bool found = false;
    for (size_t i = 0; i < dir_list_.size(); i++) {
        if (!strcmp(path, dir_list_[i].c_str())) {
            found = true;
            break;
        }
    }

    if (!found) {
        // Only process the directory if it has not already been processed.
        if (GetCommand() == Command::kMkfs && !host_path(path)) {
            // Only calculate required space if we are running mkfs, and this is a minfs path.
            ProcessDirectoryEntry(path);
            ProcessDirectoryEntry(kDot);
            ProcessDirectoryEntry(kDotDot);
        }

        dir_list_.push_back(path);
    }

    return ZX_OK;
}

zx_status_t MinfsCreator::ProcessFile(char* src, char* dst) {
    struct stat stats;
    int result = host_path(src) ? stat(src, &stats) : emu_stat(src, &stats);
    if (result < 0) {
        fprintf(stderr, "Failed to stat file %s\n", src);
        return ZX_ERR_IO;
    }

    // Check if the file already exists in file_list_.
    for (size_t n = 0; n < file_list_.size(); n++) {
        if (!strcmp(dst, file_list_[n].second.c_str())) {
            if (!strcmp(src, file_list_[n].first.c_str())) {
                return ZX_OK;
            }

            // If the file does exist but the source does not match, return an error.
            fprintf(stderr,
                    "Error: Source %s does not match existing source %s for destination %s\n",
                    src, file_list_[n].first.c_str(), dst);
            return ZX_ERR_INVALID_ARGS;
        }
    }

    if (GetCommand() == Command::kMkfs && !host_path(dst)) {
        // Only calculate required size if we are copying to minfs, and we are mkfsing.
        zx_status_t status;
        if ((status = ProcessBlocks(stats.st_size)) != ZX_OK) {
            return status;
        }

        ProcessDirectoryEntry(dst);
    }

    file_list_.push_back(std::make_pair(src, dst));
    return ZX_OK;
}

void MinfsCreator::ProcessDirectoryEntry(char* path) {
    if (path == nullptr) {
        return;
    }
    char* last_slash = strrchr(path, '/');
    last_slash = last_slash == nullptr ? path : last_slash + 1;
    size_t component_length = strlen(last_slash);
    if (component_length > std::numeric_limits<uint8_t>::max()) {
        fprintf(stderr, "component too long");
        exit(-1);
    }
    dir_bytes_ += minfs::DirentSize(static_cast<uint8_t>(component_length));
}

zx_status_t MinfsCreator::ProcessBlocks(off_t file_size) {
    uint64_t total_blocks = 0;
    uint32_t remaining = ToU32((file_size + minfs::kMinfsBlockSize - 1) / minfs::kMinfsBlockSize);

    // Add direct blocks to the total.
    uint32_t direct_blocks = fbl::min(remaining, minfs::kMinfsDirect);
    total_blocks += direct_blocks;
    remaining -= direct_blocks;

    if (remaining) {
        // If more blocks remain, calculate how many indirect blocks we need.
        uint32_t indirect_blocks = fbl::min(
            (remaining + minfs::kMinfsDirectPerIndirect + 1) / minfs::kMinfsDirectPerIndirect,
            minfs::kMinfsIndirect);

        direct_blocks = fbl::min(remaining, indirect_blocks * minfs::kMinfsDirectPerIndirect);

        // Add blocks to the total, and update remaining.
        total_blocks += indirect_blocks + direct_blocks;
        remaining -= direct_blocks;

        if (remaining) {
            // If blocks remain past the indirect block range, calculate required doubly indirect
            // and indirect blocks.
            uint32_t dindirect_blocks = fbl::min(
                (remaining + minfs::kMinfsDirectPerDindirect + 1) / minfs::kMinfsDirectPerDindirect,
                minfs::kMinfsDoublyIndirect);

            indirect_blocks = fbl::min(
                (remaining + minfs::kMinfsDirectPerIndirect + 1) / minfs::kMinfsDirectPerIndirect,
                minfs::kMinfsDirectPerIndirect * minfs::kMinfsDoublyIndirect);

            direct_blocks = fbl::min(remaining,
                                     minfs::kMinfsDoublyIndirect * minfs::kMinfsDirectPerDindirect);

            // Add blocks to the total, and update remaining.
            total_blocks += dindirect_blocks + indirect_blocks + direct_blocks;
            remaining -= direct_blocks;

            if (remaining) {
                // If we still have more blocks remaining at this point, the file is larger than
                // the current minfs max file size.
                fprintf(stderr, "Error: File too large for minfs @ %" PRIu64 " bytes\n", file_size);
                return ZX_ERR_INVALID_ARGS;
            }
        }
    }

    // Add calculated blocks to the total so far.
    data_blocks_ += total_blocks;
    return ZX_OK;
}

zx_status_t MinfsCreator::GenerateBcache(fbl::unique_ptr<minfs::Bcache>* out) {
    uint32_t block_count = static_cast<uint32_t>(GetLength() / minfs::kMinfsBlockSize);

    // Duplicate the fd so that we can re-open the minfs partition if we need to.
    int dupfd = dup(fd_.get());

    fbl::unique_ptr<minfs::Bcache> bc;
    if (minfs::Bcache::Create(&bc, std::move(fd_), block_count) < 0) {
        fprintf(stderr, "error: cannot create block cache\n");
        return ZX_ERR_IO;
    }

    bc->SetOffset(GetOffset());
    fd_.reset(dupfd);
    *out = std::move(bc);
    return ZX_OK;
}

zx_status_t MinfsCreator::MountMinfs() {
    if (emu_is_mounted()) {
        // If we have already mounted minfs, do nothing.
        return ZX_OK;
    }

    zx_status_t status;
    fbl::unique_ptr<minfs::Bcache> bc;
    if ((status = GenerateBcache(&bc)) != ZX_OK) {
        return status;
    }

    return emu_mount_bcache(std::move(bc));
}

int main(int argc, char** argv) {
    MinfsCreator minfs;

    if (minfs.ProcessAndRun(argc, argv) != ZX_OK) {
        return -1;
    }

    return 0;
}
