// Copyright 2018 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.

#include <algorithm>
#include <array>
#include <cassert>
#include <cerrno>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <dirent.h>
#include <fcntl.h>
#include <fnmatch.h>
#include <forward_list>
#include <functional>
#include <getopt.h>
#include <limits>
#include <list>
#include <memory>
#include <numeric>
#include <set>
#include <string>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <utility>
#include <vector>

#include <fbl/macros.h>
#include <fbl/unique_fd.h>
#include <lib/cksum.h>
#include <lz4/lz4frame.h>
#include <zircon/boot/image.h>

namespace {

const char* const kCmdlineWS = " \t\r\n";

bool Aligned(uint32_t length) {
    return length % ZBI_ALIGNMENT == 0;
}

// It's not clear where this magic number comes from.
constexpr size_t kLZ4FMaxHeaderFrameSize = 128;

// iovec.iov_base is void* but we only use pointers to const.
template<typename T>
iovec Iovec(const T* buffer, size_t size = sizeof(T)) {
    assert(size > 0);
    return {const_cast<void*>(static_cast<const void*>(buffer)), size};
}

class AppendBuffer {
public:
    explicit AppendBuffer(size_t size) :
        buffer_(std::make_unique<uint8_t[]>(size)), ptr_(buffer_.get()) {
    }

    size_t size() const {
        return ptr_ - buffer_.get();
    }

    iovec get() {
        return Iovec(buffer_.get(), size());
    }

    std::unique_ptr<uint8_t[]> release() {
        ptr_ = nullptr;
        return std::move(buffer_);
    }

    template<typename T>
    void Append(const T* data, size_t bytes = sizeof(T)) {
        ptr_ = static_cast<uint8_t*>(memcpy(static_cast<void*>(ptr_),
                                            static_cast<const void*>(data),
                                            bytes)) + bytes;
    }

    void Pad(size_t bytes) {
        ptr_ = static_cast<uint8_t*>(memset(static_cast<void*>(ptr_), 0,
                                            bytes)) + bytes;
    }

private:
    std::unique_ptr<uint8_t[]> buffer_;
    uint8_t* ptr_ = nullptr;
};

class Item;
using ItemPtr = std::unique_ptr<Item>;

class OutputStream {
public:
    OutputStream() = delete;

    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(OutputStream);
    OutputStream(OutputStream&&) = default;

    explicit OutputStream(fbl::unique_fd fd) : fd_(std::move(fd)) {
    }

    ~OutputStream() {
        Flush();
    }

    // Queue the iovec for output.  The second argument can transfer
    // ownership of the memory that buffer.iov_base points into.  This
    // object may refer to buffer.iov_base until Flush() completes.
    void Write(const iovec& buffer,
               std::unique_ptr<uint8_t[]> owned = nullptr) {
        assert(buffer.iov_len > 0);
        if (buffer.iov_len + total_ > UINT32_MAX - sizeof(zbi_header_t) + 1) {
            fprintf(stderr, "output size exceeds format maximum\n");
            exit(1);
        }
        total_ += static_cast<uint32_t>(buffer.iov_len);
        *write_pos_++ = buffer;
        if (write_pos_ == iov_.end()) {
            Flush();
        } else if (owned) {
            owned_buffers_.push_front(std::move(owned));
        }
    }

    uint32_t WritePosition() const {
        return total_;
    }

    void Flush() {
        auto read_pos = iov_.begin();
        while (read_pos != write_pos_) {
            read_pos = WriteBuffers(read_pos);
        }
        write_pos_ = iov_.begin();
        owned_buffers_.clear();
    }

    // Emit a placeholder.  The return value will be passed to PatchHeader.
    uint32_t PlaceHeader() {
        uint32_t pos = WritePosition();
        static const zbi_header_t dummy = {};
        Write(Iovec(&dummy));
        return pos;
    }

    // Replace a placeholder with a real header.
    void PatchHeader(const zbi_header_t& header, uint32_t place) {
        assert(place < total_);
        assert(total_ - place >= sizeof(header));

        if (flushed_ <= place) {
            // We haven't actually written it yet, so just update it in
            // memory.  A placeholder always has its own iovec, so just
            // skip over earlier ones until we hit the right offset.
            auto it = iov_.begin();
            for (place -= flushed_; place > 0; place -= it++->iov_len) {
                assert(it != write_pos_);
                assert(place >= it->iov_len);
            }
            assert(it->iov_len == sizeof(header));
            auto buffer = std::make_unique<uint8_t[]>(sizeof(header));
            it->iov_base = memcpy(buffer.get(), &header, sizeof(header));
            owned_buffers_.push_front(std::move(buffer));
        } else {
            assert(flushed_ >= place + sizeof(header));
            // Overwrite the earlier part of the file with pwrite.  This
            // does not affect the current lseek position for the next writev.
            auto buf = reinterpret_cast<const uint8_t*>(&header);
            size_t len = sizeof(header);
            while (len > 0) {
                ssize_t wrote = pwrite(fd_.get(), buf, len, place);
                if (wrote < 0) {
                    perror("pwrite on output file");
                    exit(1);
                }
                len -= wrote;
                buf += wrote;
                place += wrote;
            }
        }
    }

private:
    using IovecArray = std::array<iovec, IOV_MAX>;
    IovecArray iov_;
    IovecArray::iterator write_pos_ = iov_.begin();
    // iov_[n].iov_base might point into these buffers.  They're just
    // stored here to own the buffers until iov_ is flushed.
    std::forward_list<std::unique_ptr<uint8_t[]>> owned_buffers_;
    fbl::unique_fd fd_;
    uint32_t flushed_ = 0;
    uint32_t total_ = 0;

    bool Buffering() const {
        return write_pos_ != iov_.begin();
    }

    IovecArray::iterator WriteBuffers(IovecArray::iterator read_pos) {
        assert(read_pos != write_pos_);
        ssize_t wrote = writev(fd_.get(), &(*read_pos), write_pos_ - read_pos);
        if (wrote < 0) {
            perror("writev to output file");
            exit(1);
        }
        flushed_ += wrote;
#ifndef NDEBUG
        off_t pos = lseek(fd_.get(), 0, SEEK_CUR);
#endif
        assert(static_cast<off_t>(flushed_) == pos ||
               (pos == -1 && errno == ESPIPE));
        // Skip all the buffers that were wholly written.
        while (wrote >= read_pos->iov_len) {
            wrote -= read_pos->iov_len;
            ++read_pos;
            if (wrote == 0) {
                break;
            }
            assert(read_pos != write_pos_);
        }
        if (wrote > 0) {
            // writev wrote only part of this buffer.  Do the rest next time.
            read_pos->iov_len -= wrote;
            read_pos->iov_base = static_cast<void*>(
                static_cast<uint8_t*>(read_pos->iov_base) + wrote);
        }
        return read_pos;
    }
};

class FileWriter {
public:
    FileWriter(const char* outfile, std::string prefix) :
        prefix_(std::move(prefix)), outfile_(outfile) {
    }

    unsigned int NextFileNumber() const {
        return files_ + 1;
    }

    OutputStream RawFile(const char* name) {
        ++files_;
        if (outfile_) {
            if (files_ > 1) {
                fprintf(stderr,
                        "--output (-o) cannot write second file %s\n", name);
                exit(1);
            } else {
                return CreateFile(outfile_);
            }
        } else {
            auto file = prefix_ + name;
            return CreateFile(file.c_str());
        }
    }

private:
    std::string prefix_;
    const char* outfile_ = nullptr;
    unsigned int files_ = 0;

    OutputStream CreateFile(const char* outfile) {
        // Remove the file in case it exists.  This makes it safe to
        // to do e.g. `zbi -o boot.zbi boot.zbi --entry=bin/foo=mybuild/foo`
        // to modify a file "in-place" because the input `boot.zbi` will
        // already have been opened before the new `boot.zbi` is created.
        remove(outfile);

        fbl::unique_fd fd(open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666));
        if (!fd && errno == ENOENT) {
            MakeDirs(outfile);
            fd.reset(open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666));
        }
        if (!fd) {
            fprintf(stderr, "cannot create %s: %s\n",
                    outfile, strerror(errno));
            exit(1);
        }

        return OutputStream(std::move(fd));
    }

    static void MakeDirs(const std::string& name) {
        auto lastslash = name.rfind('/');
        if (lastslash == std::string::npos) {
            return;
        }
        auto dir = name.substr(0, lastslash);
        if (mkdir(dir.c_str(), 0777) == 0) {
            return;
        }
        if (errno == ENOENT) {
            MakeDirs(dir);
            if (mkdir(dir.c_str(), 0777) == 0) {
                return;
            }
        }
        if (errno != EEXIST) {
            fprintf(stderr, "mkdir: %s: %s\n",
                    dir.c_str(), strerror(errno));
            exit(1);
        }
    }
};

class NameMatcher {
public:
    NameMatcher(const char* const* patterns, int count) :
        begin_(patterns), end_(&patterns[count]) {
        assert(count >= 0);
        assert(!patterns[count]);
    }
    NameMatcher(char** argv, int argi, int argc) :
        NameMatcher(&argv[argi], argc - argi) {
    }

    unsigned int names_checked() const { return names_checked_; }
    unsigned int names_matched() const { return names_matched_; }

    bool MatchesAll(void) const { return begin_ == end_; }

    // Not const because it keeps stats.
    bool Matches(const char* name, bool casefold = false) {
        ++names_checked_;
        if (MatchesAll() || PatternMatch(name, casefold)) {
            ++names_matched_;
            return true;
        } else {
            return false;
        }
    }

    void Summary(const char* verbed, const char* items, bool verbose) {
        if (!MatchesAll()) {
            if (names_checked() == 0) {
                fprintf(stderr, "no %s\n", items);
                exit(1);
            } else if (names_matched() == 0) {
                fprintf(stderr, "no matching %s\n", items);
                exit(1);
            } else if (verbose) {
                printf("%s %u of %u %s\n",
                       verbed, names_matched(), names_checked(), items);
            }
        }
    }

private:
    const char* const* const begin_ = nullptr;
    const char* const* const end_ = nullptr;
    unsigned int names_checked_ = 0;
    unsigned int names_matched_ = 0;

    bool PatternMatch(const char* name, bool casefold) const {
        for (auto next = begin_; next != end_; ++next) {
            if (fnmatch(*next, name, casefold ? FNM_CASEFOLD : 0) == 0) {
                return true;
            }
        }
        return false;
    }
};

class Checksummer {
public:
    void Write(const iovec& buffer) {
        crc_ = crc32(crc_, static_cast<const uint8_t*>(buffer.iov_base),
                     buffer.iov_len);
    }

    void Write(const std::list<const iovec>& list) {
        for (const auto& buffer : list) {
            Write(buffer);
        }
    }

    void FinalizeHeader(zbi_header_t* header) {
        header->crc32 = 0;
        uint32_t header_crc = crc32(
            0, reinterpret_cast<const uint8_t*>(header), sizeof(*header));
        header->crc32 = crc32_combine(header_crc, crc_, header->length);
    }

private:
    uint32_t crc_ = 0;
};

// This tells LZ4f_compressUpdate it can keep a pointer to data.
constexpr const LZ4F_compressOptions_t kCompressOpt  = { 1, {} };

class Compressor {
public:
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Compressor);
    Compressor() = default;

#define LZ4F_CALL(func, ...)                                            \
    [&](){                                                              \
        auto result = func(__VA_ARGS__);                                \
        if (LZ4F_isError(result)) {                                     \
            fprintf(stderr, "%s: %s\n", #func, LZ4F_getErrorName(result)); \
            exit(1);                                                    \
        }                                                               \
        return result;                                                  \
    }()

    void Init(OutputStream* out, const zbi_header_t& header) {
        header_ = header;
        assert(header_.flags & ZBI_FLAG_STORAGE_COMPRESSED);
        assert(header_.flags & ZBI_FLAG_CRC32);

        // Write a place-holder for the header, which we will go back
        // and fill in once we know the payload length and CRC.
        header_pos_ = out->PlaceHeader();

        prefs_.frameInfo.contentSize = header_.length;

        prefs_.frameInfo.blockSizeID = LZ4F_max64KB;
        prefs_.frameInfo.blockMode = LZ4F_blockIndependent;

        // LZ4 compression levels 1-3 are for "fast" compression, and 4-16
        // are for higher compression. The additional compression going from
        // 4 to 16 is not worth the extra time needed during compression.
        prefs_.compressionLevel = 4;

        LZ4F_CALL(LZ4F_createCompressionContext, &ctx_, LZ4F_VERSION);

        // Record the original uncompressed size in header_.extra.
        // WriteBuffer will accumulate the compressed size in header_.length.
        header_.extra = header_.length;
        header_.length = 0;

        // This might start writing compression format headers before it
        // receives any data.
        auto buffer = GetBuffer(kLZ4FMaxHeaderFrameSize);
        size_t size = LZ4F_CALL(LZ4F_compressBegin, ctx_,
                                buffer.data.get(), buffer.size, &prefs_);
        assert(size <= buffer.size);
        WriteBuffer(out, std::move(buffer), size);
    }

    ~Compressor() {
        LZ4F_CALL(LZ4F_freeCompressionContext, ctx_);
    }

    // NOTE: Input buffer may be referenced for the life of the Compressor!
    void Write(OutputStream* out, const iovec& input) {
        auto buffer = GetBuffer(LZ4F_compressBound(input.iov_len, &prefs_));
        size_t actual_size = LZ4F_CALL(LZ4F_compressUpdate,
                                       ctx_, buffer.data.get(), buffer.size,
                                       input.iov_base, input.iov_len,
                                       &kCompressOpt);
        WriteBuffer(out, std::move(buffer), actual_size);
    }

    uint32_t Finish(OutputStream* out) {
        // Write the closing chunk from the compressor.
        auto buffer = GetBuffer(LZ4F_compressBound(0, &prefs_));
        size_t actual_size = LZ4F_CALL(LZ4F_compressEnd,
                                       ctx_, buffer.data.get(), buffer.size,
                                       &kCompressOpt);

        WriteBuffer(out, std::move(buffer), actual_size);

        // Complete the checksum.
        crc_.FinalizeHeader(&header_);

        // Write the header back where its place was held.
        out->PatchHeader(header_, header_pos_);
        return header_.length;
    }

private:
    struct Buffer {
        // Move-only type: after moving, data is nullptr and size is 0.
        Buffer() = default;
        Buffer(std::unique_ptr<uint8_t[]> buffer, size_t max_size) :
            data(std::move(buffer)), size(max_size) {
        }
        Buffer(Buffer&& other) {
            *this = std::move(other);
        }
        Buffer& operator=(Buffer&& other) {
            data = std::move(other.data);
            size = other.size;
            other.size = 0;
            return *this;
        }
        std::unique_ptr<uint8_t[]> data;
        size_t size = 0;
    } unused_buffer_;
    zbi_header_t header_;
    Checksummer crc_;
    LZ4F_compressionContext_t ctx_;
    LZ4F_preferences_t prefs_{};
    uint32_t header_pos_ = 0;
    // IOV_MAX buffers might be live at once.
    static constexpr const size_t kMinBufferSize = (128 << 20) / IOV_MAX;

    Buffer GetBuffer(size_t max_size) {
        if (unused_buffer_.size >= max_size) {
            // We have an old buffer that will do fine.
            return std::move(unused_buffer_);
        } else {
            // Get a new buffer.
            max_size = std::max(max_size, kMinBufferSize);
            return {std::make_unique<uint8_t[]>(max_size), max_size};
        }
    }

    void WriteBuffer(OutputStream* out, Buffer buffer, size_t actual_size) {
        if (actual_size > 0) {
            header_.length += actual_size;
            const iovec iov{buffer.data.get(), actual_size};
            crc_.Write(iov);
            out->Write(iov, std::move(buffer.data));
            buffer.size = 0;
        } else {
            // The compressor often delivers zero bytes for an input chunk.
            // Stash the unused buffer for next time to cut down on new/delete.
            unused_buffer_ = std::move(buffer);
        }
    }
};

const size_t Compressor::kMinBufferSize;

constexpr const LZ4F_decompressOptions_t kDecompressOpt{};

std::unique_ptr<uint8_t[]> Decompress(const std::list<const iovec>& payload,
                                      uint32_t decompressed_length) {
    auto buffer = std::make_unique<uint8_t[]>(decompressed_length);

    LZ4F_decompressionContext_t ctx;
    LZ4F_CALL(LZ4F_createDecompressionContext, &ctx, LZ4F_VERSION);

    uint8_t* dst = buffer.get();
    size_t dst_size = decompressed_length;
    for (const auto& iov : payload) {
        auto src = static_cast<const uint8_t*>(iov.iov_base);
        size_t src_size = iov.iov_len;
        do {
            if (dst_size == 0) {
                fprintf(stderr, "decompression produced too much data\n");
                exit(1);
            }

            size_t nwritten = dst_size, nread = src_size;
            LZ4F_CALL(LZ4F_decompress, ctx, dst, &nwritten, src, &nread,
                      &kDecompressOpt);

            assert(nread <= src_size);
            src += nread;
            src_size -= nread;

            assert(nwritten <= dst_size);
            dst += nwritten;
            dst_size -= nwritten;
        } while (src_size > 0);
    }
    if (dst_size > 0) {
        fprintf(stderr,
                "decompression produced too little data by %zu bytes\n",
                dst_size);
        exit(1);
    }

    LZ4F_CALL(LZ4F_freeDecompressionContext, ctx);

    return buffer;
}

#undef LZ4F_CALL

class FileContents {
public:
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FileContents);
    FileContents() = default;

    // Get unowned file contents from a BOOTFS image.
    // The entry has been validated against the payload size.
    FileContents(const zbi_bootfs_dirent_t& entry,
                 const uint8_t* bootfs_payload) :
        mapped_(const_cast<void*>(static_cast<const void*>(bootfs_payload +
                                                           entry.data_off))),
        mapped_size_(ZBI_BOOTFS_PAGE_ALIGN(entry.data_len)),
        exact_size_(entry.data_len),
        owned_(false) {
    }

    // Get unowned file contents from a string.
    // This object won't support PageRoundedView.
    FileContents(const char* buffer, bool null_terminate) :
        mapped_(const_cast<char*>(buffer)), mapped_size_(strlen(buffer) + 1),
        exact_size_(mapped_size_ - (null_terminate ? 0 : 1)), owned_(false) {
    }

    FileContents(FileContents&& other) {
        *this = std::move(other);
    }

    FileContents& operator=(FileContents&& other) {
        std::swap(mapped_, other.mapped_);
        std::swap(mapped_size_, other.mapped_size_);
        std::swap(exact_size_, other.exact_size_);
        std::swap(owned_, other.owned_);
        return *this;
    }

    ~FileContents() {
        if (owned_ && mapped_) {
            munmap(mapped_, mapped_size_);
        }
    }

    size_t exact_size() const { return exact_size_; }
    size_t mapped_size() const { return mapped_size_; }

    static FileContents Map(const fbl::unique_fd& fd,
                            const struct stat& st,
                            const char* filename) {
        // st_size is off_t, everything else is size_t.
        const size_t size = st.st_size;
        static_assert(std::numeric_limits<decltype(st.st_size)>::max() <=
                      std::numeric_limits<size_t>::max(), "size_t < off_t?");

        static size_t pagesize = []() -> size_t {
            size_t pagesize = sysconf(_SC_PAGE_SIZE);
            assert(pagesize >= ZBI_BOOTFS_PAGE_SIZE);
            assert(pagesize % ZBI_BOOTFS_PAGE_SIZE == 0);
            return pagesize;
        }();

        void* map = mmap(nullptr, size,
                         PROT_READ, MAP_FILE | MAP_PRIVATE, fd.get(), 0);
        if (map == MAP_FAILED) {
            fprintf(stderr, "mmap: %s: %s\n", filename, strerror(errno));
            exit(1);
        }
        assert(map);

        FileContents result;
        result.mapped_ = map;
        result.exact_size_ = size;
        result.mapped_size_ = (size + pagesize - 1) & -pagesize;
        return result;
    }

    const iovec View(size_t offset, size_t length) const {
        assert(length > 0);
        assert(offset < exact_size_);
        assert(exact_size_ - offset >= length);
        return Iovec(static_cast<const uint8_t*>(mapped_) + offset, length);
    }

    const iovec PageRoundedView(size_t offset, size_t length) const {
        assert(length > 0);
        assert(offset < mapped_size_);
        assert(mapped_size_ - offset >= length);
        return Iovec(static_cast<const uint8_t*>(mapped_) + offset, length);
    }

private:
    void* mapped_ = nullptr;
    size_t mapped_size_ = 0;
    size_t exact_size_ = 0;
    bool owned_ = true;
};

class FileOpener {
public:
    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(FileOpener);
    FileOpener() = default;

    void Init(const char* output_file, const char* depfile) {
        if (depfile) {
            depfile_ = fopen(depfile, "w");
            if (!depfile_) {
                perror(depfile);
                exit(1);
            }
            fprintf(depfile_, "%s:", output_file);
        }
    }

    fbl::unique_fd Open(const char* file, struct stat* st = nullptr) {
        fbl::unique_fd fd(open(file, O_RDONLY));
        if (!fd) {
            perror(file);
            exit(1);
        }
        if (st && fstat(fd.get(), st) < 0) {
            perror("fstat");
            exit(1);
        }
        if (depfile_) {
            fprintf(depfile_, " %s", file);
        }
        return fd;
    }

    fbl::unique_fd Open(const std::string& file, struct stat* st = nullptr) {
        return Open(file.c_str(), st);
    }

    ~FileOpener() {
        if (depfile_) {
            fputc('\n', depfile_);
            fclose(depfile_);
        }
    }

private:
    FILE* depfile_ = nullptr;
};

void RequireRegularFile(const struct stat& st, const char* file) {
    if (!S_ISREG(st.st_mode)) {
        fprintf(stderr, "%s: not a regular file\n", file);
        exit(1);
    }
}

class GroupFilter {
public:
    DISALLOW_COPY_ASSIGN_AND_MOVE(GroupFilter);
    GroupFilter() = default;

    void SetFilter(const char* groups) {
        if (!strcmp(groups, "all")) {
            groups_.reset();
        } else {
            groups_ = std::make_unique<std::set<std::string>>();
            while (const char *p = strchr(groups, ',')) {
                groups_->emplace(groups, p - groups);
                groups = p + 1;
            }
            groups_->emplace(groups);
        }
    }

    bool AllowsAll() const {
        return !groups_;
    }

    bool Allows(const std::string& group) const {
        return AllowsAll() || groups_->find(group) != groups_->end();
    }

private:
    std::unique_ptr<std::set<std::string>> groups_;
};

// Base class for ManifestInputFileGenerator and DirectoryInputFileGenerator.
// These both deliver target name -> file contents mappings until they don't.
struct InputFileGenerator {
    struct value_type {
        std::string target;
        FileContents file;
    };
    virtual ~InputFileGenerator() = default;
    virtual bool Next(FileOpener*, const std::string& prefix, value_type*) = 0;
};

using InputFileGeneratorList =
    std::deque<std::unique_ptr<InputFileGenerator>>;

class ManifestInputFileGenerator : public InputFileGenerator {
public:
    ManifestInputFileGenerator(FileContents file, std::string prefix,
                               const GroupFilter* filter) :
        file_(std::move(file)), prefix_(std::move(prefix)), filter_(filter) {
        read_ptr_ = static_cast<const char*>(
            file_.View(0, file_.exact_size()).iov_base);
        eof_ = read_ptr_ + file_.exact_size();
    }

    ~ManifestInputFileGenerator() override = default;

    bool Next(FileOpener* opener, const std::string& prefix,
              value_type* value) override {
        while (read_ptr_ != eof_) {
            auto eol = static_cast<const char*>(
                memchr(read_ptr_, '\n', eof_ - read_ptr_));
            auto line = read_ptr_;
            if (eol) {
                read_ptr_ = eol + 1;
            } else {
                read_ptr_ = eol = eof_;
            }
            auto eq = static_cast<const char*>(memchr(line, '=', eol - line));
            if (!eq) {
                fprintf(stderr, "manifest entry has no '=' separator: %.*s\n",
                        static_cast<int>(eol - line), line);
                exit(1);
            }

            line = AllowEntry(line, eq, eol);
            if (line) {
                std::string target(line, eq - line);
                std::string source(eq + 1, eol - (eq + 1));
                struct stat st;
                auto fd = opener->Open(source, &st);
                RequireRegularFile(st, source.c_str());
                auto file = FileContents::Map(fd, st, source.c_str());
                *value = value_type{prefix + target, std::move(file)};
                return true;
            }
        }
        return false;
    }

private:
    FileContents file_;
    const std::string prefix_;
    const GroupFilter* filter_ = nullptr;
    const char* read_ptr_ = nullptr;
    const char* eof_ = nullptr;

    // Returns the beginning of the `target=source` portion of the entry
    // if the entry is allowed by the filter, otherwise nullptr.
    const char* AllowEntry(const char* start, const char* eq, const char* eol) {
        if (*start != '{') {
            // This entry doesn't specify a group.
            return filter_->AllowsAll() ? start : nullptr;
        }
        auto end_group = static_cast<const char*>(
            memchr(start + 1, '}', eq - start));
        if (!end_group) {
            fprintf(stderr,
                    "manifest entry has '{' but no '}': %.*s\n",
                    static_cast<int>(eol - start), start);
            exit(1);
        }
        std::string group(start, end_group - start);
        return filter_->Allows(group) ? end_group + 1 : nullptr;
    }
};

class DirectoryInputFileGenerator : public InputFileGenerator {
public:
    DirectoryInputFileGenerator(fbl::unique_fd fd, std::string prefix) :
        source_prefix_(std::move(prefix)) {
        walk_pos_.emplace_front(MakeUniqueDir(std::move(fd)), 0);
    }

    ~DirectoryInputFileGenerator() override = default;

    bool Next(FileOpener* opener, const std::string& prefix,
              value_type* value) override {
        do {
            const dirent* d = readdir(walk_pos_.front().dir.get());
            if (!d) {
                Ascend();
                continue;
            }
            if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) {
                continue;
            }
            std::string target = prefix + walk_prefix_ + d->d_name;
            std::string source = source_prefix_ + walk_prefix_ + d->d_name;
            struct stat st;
            auto fd = opener->Open(source, &st);
            if (S_ISDIR(st.st_mode)) {
                Descend(std::move(fd), d->d_name);
            } else {
                RequireRegularFile(st, source.c_str());
                auto file = FileContents::Map(std::move(fd), st,
                                              source.c_str());
                *value = value_type{std::move(target), std::move(file)};
                return true;
            }
        } while (!walk_pos_.empty());
        return false;
    }

private:
    // std::unique_ptr for fdopendir/closedir.
    static void DeleteUniqueDir(DIR* dir) {
        closedir(dir);
    }
    using UniqueDir = std::unique_ptr<DIR, decltype(&DeleteUniqueDir)>;
    UniqueDir MakeUniqueDir(fbl::unique_fd fd) {
        DIR* dir = fdopendir(fd.release());
        if (!dir) {
            perror("fdopendir");
            exit(1);
        }
        return UniqueDir(dir, &DeleteUniqueDir);
    }

    // State of our depth-first directory tree walk.
    struct WalkState {
        WalkState(UniqueDir d, size_t len) :
            dir(std::move(d)), parent_prefix_len(len) {
        }
        UniqueDir dir;
        size_t parent_prefix_len;
    };

    const std::string source_prefix_;
    std::forward_list<WalkState> walk_pos_;
    std::string walk_prefix_;

    void Descend(fbl::unique_fd fd, const char* name) {
        size_t parent = walk_prefix_.size();
        walk_prefix_ += name;
        walk_prefix_ += "/";
        walk_pos_.emplace_front(MakeUniqueDir(std::move(fd)), parent);
    }

    void Ascend() {
        walk_prefix_.resize(walk_pos_.front().parent_prefix_len);
        walk_pos_.pop_front();
    }
};

class Item {
public:
    // Only the static methods below can create an Item.
    Item() = delete;

    DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(Item);

    static const char* TypeName(uint32_t zbi_type) {
        return ItemTypeInfo(zbi_type).name;
    }

    static bool ParseTypeName(const char* name, uint32_t* abi_type) {
        for (const auto& t : kItemTypes_) {
            if (!strcasecmp(t.name, name)) {
                *abi_type = t.type;
                return true;
            }
        }
        int i = 0;
        return sscanf(name, "%x%n", abi_type, &i) == 1 && name[i] == '\0';
    }

    static std::string ExtractedFileName(unsigned int n, uint32_t zbi_type,
                                         bool raw) {
        std::string name;
        char buf[32];
        const auto info = ItemTypeInfo(zbi_type);
        if (info.name) {
            snprintf(buf, sizeof(buf), "%03u.", n);
            name = buf;
            name += info.name;
            for (auto& c : name) {
                c = std::tolower(c);
            }
        } else {
            snprintf(buf, sizeof(buf), "%03u.%08x", n, zbi_type);
            name = buf;
        }
        name += (raw && info.extension) ? info.extension : ".zbi";
        return name;
    }

    static void PrintTypeUsage(FILE* out) {
        fprintf(out, "\
TYPE can be hexadecimal or a name string (case-insensitive).\n\
Extracted items use the file names shown below:\n\
    --type               --extract-item             --extract-raw\n\
");
        for (const auto& t : kItemTypes_) {
            const auto zbi_name = ExtractedFileName(1, t.type, false);
            const auto raw_name = ExtractedFileName(1, t.type, true);
            fprintf(out, "    %-20s %-26s %s\n",
                    t.name, zbi_name.c_str(), raw_name.c_str());
        }
    }

    static bool TypeIsStorage(uint32_t zbi_type) {
        return (zbi_type == ZBI_TYPE_STORAGE_BOOTFS ||
                zbi_type == ZBI_TYPE_STORAGE_RAMDISK);
    }

    uint32_t type() const {
        return header_.type;
    }

    uint32_t PayloadSize() const {
        return header_.length;
    }

    uint32_t TotalSize() const {
        return sizeof(header_) + ZBI_ALIGN(PayloadSize());
    }

    void Describe(uint32_t pos) const {
        const char* type_name = TypeName(type());
        if (!type_name) {
            printf("%08x: %08x UNKNOWN (type=%08x)\n",
                   pos, header_.length, header_.type);
        } else if (TypeIsStorage(type())) {
            printf("%08x: %08x %s (size=%08x)\n",
                   pos, header_.length, type_name, header_.extra);
        } else {
            printf("%08x: %08x %s\n",
                   pos, header_.length, type_name);
        }
        if (header_.flags & ZBI_FLAG_CRC32) {
            auto print_crc = [](const zbi_header_t& header) {
                printf("        :          MAGIC=%08x CRC=%08x\n",
                       header.magic, header.crc32);
            };

            Checksummer crc;
            crc.Write(payload_);
            zbi_header_t check_header = header_;
            crc.FinalizeHeader(&check_header);

            if (compress_) {
                // We won't compute it until StreamCompressed, so
                // write out the computation we just did to check.
                print_crc(check_header);
            } else {
                print_crc(header_);
                if (check_header.crc32 != header_.crc32) {
                    fprintf(stderr, "error: CRC %08x does not match header\n",
                            check_header.crc32);
                }
            }
        } else {
            printf("        :          MAGIC=%08x NO CRC\n", header_.magic);
        }
    }

    bool AlreadyCompressed() const {
        return (header_.flags & ZBI_FLAG_STORAGE_COMPRESSED) && !compress_;
    }

    int Show() {
        if (header_.length > 0) {
            if (AlreadyCompressed()) {
                return CreateFromCompressed(*this)->Show();
            }
            switch (header_.type) {
            case ZBI_TYPE_STORAGE_BOOTFS:
                return ShowBootFS();
            case ZBI_TYPE_CMDLINE:
                return ShowCmdline();
            }
        }
        return 0;
    }

    // Streaming exhausts the item's payload.  The OutputStream will now
    // have pointers into buffers owned by this Item, so this Item must be
    // kept alive until out->Flush() runs (while *this is alive, to be safe).
    void Stream(OutputStream* out) {
        assert(Aligned(out->WritePosition()));
        uint32_t wrote = compress_ ? StreamCompressed(out) : StreamRaw(out);
        assert(out->WritePosition() % ZBI_ALIGNMENT == wrote % ZBI_ALIGNMENT);
        uint32_t aligned = ZBI_ALIGN(wrote);
        if (aligned > wrote) {
            static const uint8_t padding[ZBI_ALIGNMENT]{};
            out->Write(Iovec(padding, aligned - wrote));
        }
        assert(Aligned(out->WritePosition()));
    }

    // The buffer will be released when this Item is destroyed.  This item
    // and items earlier on the list can hold pointers into the buffer.
    void OwnBuffer(std::unique_ptr<uint8_t[]> buffer) {
        buffers_.push_front(std::move(buffer));
    }
    void OwnFile(FileContents file) {
        files_.push_front(std::move(file));
    }

    // Consume another Item while keeping its owned buffers and files alive.
    void TakeOwned(ItemPtr other) {
        if (other) {
            buffers_.splice_after(buffers_.before_begin(), other->buffers_);
            files_.splice_after(files_.before_begin(), other->files_);
        }
    }

    // Create from in-core data.
    static ItemPtr CreateFromBuffer(
        uint32_t type, std::unique_ptr<uint8_t[]> payload, size_t size) {
        auto item = MakeItem(NewHeader(type, size));
        item->payload_.emplace_front(Iovec(payload.get(), size));
        item->OwnBuffer(std::move(payload));
        Checksummer crc;
        crc.Write(item->payload_);
        crc.FinalizeHeader(&item->header_);
        return item;
    }

    // Create from local scratch data.
    template<typename T>
    static ItemPtr Create(uint32_t type, const T& payload) {
        auto buffer = std::make_unique<uint8_t[]>(sizeof(payload));
        memcpy(buffer.get(), &payload, sizeof(payload));
        return CreateFromBuffer(type, std::move(buffer), sizeof(payload));
    }

    // Create from raw file contents.
    static ItemPtr CreateFromFile(
        FileContents file, uint32_t type, bool compress) {
        bool null_terminate = type == ZBI_TYPE_CMDLINE;
        compress = compress && TypeIsStorage(type);

        size_t size = file.exact_size() + (null_terminate ? 1 : 0);
        auto item = MakeItem(NewHeader(type, size), compress);

        // If we need some zeros, see if they're already right there
        // in the last mapped page past the exact end of the file.
        if (size <= file.mapped_size()) {
            // Use the padding that's already there.
            item->payload_.emplace_front(file.PageRoundedView(0, size));
        } else {
            // No space, so we need a separate padding buffer.
            if (null_terminate) {
                item->payload_.emplace_front(Iovec("", 1));
            }
            item->payload_.emplace_front(file.View(0, file.exact_size()));
        }

        if (!compress) {
            // Compute the checksum now so the item is ready to write out.
            Checksummer crc;
            crc.Write(file.View(0, file.exact_size()));
            if (null_terminate) {
                crc.Write(Iovec("", 1));
            }
            crc.FinalizeHeader(&item->header_);
        }

        // The item now owns the file mapping that its payload points into.
        item->OwnFile(std::move(file));

        return item;
    }

    // Create from an existing fully-baked item in an input file.
    static ItemPtr CreateFromItem(const FileContents& file,
                                                uint32_t offset) {
        if (offset > file.exact_size() ||
            file.exact_size() - offset < sizeof(zbi_header_t)) {
            fprintf(stderr, "input file too short for next header\n");
            exit(1);
        }
        const zbi_header_t* header = static_cast<const zbi_header_t*>(
            file.View(offset, sizeof(zbi_header_t)).iov_base);
        offset += sizeof(zbi_header_t);
        if (file.exact_size() - offset < header->length) {
            fprintf(stderr, "input file too short for payload of %u bytes\n",
                    header->length);
            exit(1);
        }
        auto item = MakeItem(*header);
        item->payload_.emplace_front(file.View(offset, header->length));
        return item;
    }

    // Create by decompressing a fully-baked item that is compressed.
    static ItemPtr CreateFromCompressed(const Item& compressed) {
        assert(compressed.AlreadyCompressed());
        auto item = MakeItem(compressed.header_);
        item->header_.flags &= ~ZBI_FLAG_STORAGE_COMPRESSED;
        item->header_.length = item->header_.extra;
        auto buffer = Decompress(compressed.payload_, item->header_.length);
        item->payload_.emplace_front(
            Iovec(buffer.get(), item->header_.length));
        item->OwnBuffer(std::move(buffer));
        return item;
    }

    // Same, but consumes the compressed item while keeping its
    // owned buffers alive in the new uncompressed item.
    static ItemPtr CreateFromCompressed(ItemPtr compressed) {
        auto uncompressed = CreateFromCompressed(*compressed);
        uncompressed->TakeOwned(std::move(compressed));
        return uncompressed;
    }

    // Create a BOOTFS item.
    template<typename Filter>
    static ItemPtr CreateBootFS(FileOpener* opener,
                                const InputFileGeneratorList& input,
                                const Filter& include_file,
                                bool sort,
                                const std::string& prefix,
                                bool compress) {
        auto item = MakeItem(NewHeader(ZBI_TYPE_STORAGE_BOOTFS, 0), compress);

        // Collect the names and exact sizes here and the contents in payload_.
        struct Entry {
            std::string name;
            uint32_t data_len = 0;
        };
        std::deque<Entry> entries;
        size_t dirsize = 0, bodysize = 0;
        for (const auto& generator : input) {
            InputFileGenerator::value_type next;
            while (generator->Next(opener, prefix, &next)) {
                if (!include_file(next.target.c_str())) {
                    continue;
                }
                // Accumulate the space needed for each zbi_bootfs_dirent_t.
                dirsize += ZBI_BOOTFS_DIRENT_SIZE(next.target.size() + 1);
                Entry entry;
                entry.name.swap(next.target);
                entry.data_len = static_cast<uint32_t>(next.file.exact_size());
                if (entry.data_len != next.file.exact_size()) {
                    fprintf(stderr,
                            "input file size exceeds format maximum\n");
                    exit(1);
                }
                uint32_t size = ZBI_BOOTFS_PAGE_ALIGN(entry.data_len);
                bodysize += size;
                item->payload_.emplace_back(
                    next.file.PageRoundedView(0, size));
                entries.push_back(std::move(entry));
                item->OwnFile(std::move(next.file));
            }
        }

        if (sort) {
            std::sort(entries.begin(), entries.end(),
                      [](const Entry& a, const Entry& b) {
                          return a.name < b.name;
                      });
        }

        // Now we can calculate the final sizes.
        const zbi_bootfs_header_t header = {
            ZBI_BOOTFS_MAGIC,               // magic
            static_cast<uint32_t>(dirsize), // dirsize
            0,                              // reserved0
            0,                              // reserved1
        };
        size_t header_size = ZBI_BOOTFS_PAGE_ALIGN(sizeof(header) + dirsize);
        item->header_.length = static_cast<uint32_t>(header_size + bodysize);
        if (item->header_.length != header_size + bodysize) {
            fprintf(stderr, "BOOTFS image size exceeds format maximum\n");
            exit(1);
        }

        // Now fill a buffer with the BOOTFS header and directory entries.
        AppendBuffer buffer(header_size);
        buffer.Append(&header);
        uint32_t data_off = static_cast<uint32_t>(header_size);
        for (const auto& file : item->payload_) {
            const auto& entry = entries.front();
            const zbi_bootfs_dirent_t entry_hdr = {
                static_cast<uint32_t>(entry.name.size() + 1), // name_len
                entry.data_len,                               // data_len
                data_off,                                     // data_off
            };
            data_off += static_cast<uint32_t>(file.iov_len);
            buffer.Append(&entry_hdr);
            buffer.Append(entry.name.c_str(), entry_hdr.name_len);
            buffer.Pad(
                ZBI_BOOTFS_DIRENT_SIZE(entry_hdr.name_len) -
                offsetof(zbi_bootfs_dirent_t, name[entry_hdr.name_len]));
            entries.pop_front();
        }
        assert(data_off == item->header_.length);
        // Zero fill to the end of the page.
        buffer.Pad(header_size - buffer.size());

        if (!compress) {
            // Checksum the BOOTFS image right now: header and then payload.
            Checksummer crc;
            crc.Write(buffer.get());
            crc.Write(item->payload_);
            crc.FinalizeHeader(&item->header_);
        }

        // Put the header at the front of the payload.
        item->payload_.emplace_front(buffer.get());
        item->OwnBuffer(buffer.release());

        return item;
    }

    // The generator consumes the Item.  The FileContents it generates
    // point into the Item's storage, so the generator must be kept
    // alive as long as any of those FileContents is alive.
    static auto ReadBootFS(ItemPtr item) {
        return std::unique_ptr<InputFileGenerator>(
            new BootFSInputFileGenerator(std::move(item)));
    }

    void ExtractItem(FileWriter* writer, NameMatcher* matcher) {
        std::string namestr = ExtractedFileName(writer->NextFileNumber(),
                                                type(), false);
        auto name = namestr.c_str();
        if (matcher->Matches(name, true)) {
            WriteZBI(writer, name, (Item*const[]){this});
        }
    }

    void ExtractRaw(FileWriter* writer, NameMatcher* matcher) {
        std::string namestr = ExtractedFileName(writer->NextFileNumber(),
                                                type(), true);
        auto name = namestr.c_str();
        if (matcher->Matches(name, true)) {
            if (type() == ZBI_TYPE_CMDLINE) {
                // Drop a trailing NUL.
                iovec iov = payload_.back();
                auto str = static_cast<const char*>(iov.iov_base);
                if (str[iov.iov_len - 1] == '\0') {
                    payload_.pop_back();
                    --iov.iov_len;
                    payload_.push_back(iov);
                }
            }
            if (AlreadyCompressed()) {
                auto uncompressed = CreateFromCompressed(*this);
                // The uncompressed item must outlive the OutputStream.
                auto out = writer->RawFile(name);
                uncompressed->StreamRawPayload(&out);
            } else {
                auto out = writer->RawFile(name);
                StreamRawPayload(&out);
            }
        }
    }

    template<typename ItemList>
    static void WriteZBI(FileWriter* writer, const char* name,
                         const ItemList& items) {
        auto out = writer->RawFile(name);

        uint32_t header_start = out.PlaceHeader();
        uint32_t payload_start = out.WritePosition();
        assert(Aligned(payload_start));

        for (const auto& item : items) {
            // The OutputStream stores pointers into Item buffers in its write
            // queue until it goes out of scope below.  The ItemList keeps all
            // the items alive past then.
            item->Stream(&out);
        }

        const zbi_header_t header = {
            ZBI_TYPE_CONTAINER,                  // type
            out.WritePosition() - payload_start, // length
            ZBI_CONTAINER_MAGIC,                 // extra
            ZBI_FLAG_VERSION,                    // flags
            0,                                   // reserved0
            0,                                   // reserved1
            ZBI_ITEM_MAGIC,                      // magic
            ZBI_ITEM_NO_CRC32,                   // crc32
        };
        assert(Aligned(header.length));
        out.PatchHeader(header, header_start);
    }

    void AppendPayload(std::string* buffer) const {
        if (AlreadyCompressed()) {
            CreateFromCompressed(*this)->AppendPayload(buffer);
        } else {
            for (const auto& iov : payload_) {
                buffer->append(static_cast<const char*>(iov.iov_base),
                               iov.iov_len);
            }
        }
    }

private:
    zbi_header_t header_;
    std::list<const iovec> payload_;
    // The payload_ items might point into these buffers.  They're just
    // stored here to own the buffers until the payload is exhausted.
    std::forward_list<FileContents> files_;
    std::forward_list<std::unique_ptr<uint8_t[]>> buffers_;
    const bool compress_;

    struct ItemTypeInfo {
        uint32_t type;
        const char* name;
        const char* extension;
    };
    static constexpr const ItemTypeInfo kItemTypes_[] = {
#define kITemTypes_Element(type, name, extension) {type, name, extension},
    ZBI_ALL_TYPES(kITemTypes_Element)
#undef kitemtypes_element
};;

    static constexpr ItemTypeInfo ItemTypeInfo(uint32_t zbi_type) {
        for (const auto& t : kItemTypes_) {
            if (t.type == zbi_type) {
                return t;
            }
        }
        return {};
    }

    static constexpr zbi_header_t NewHeader(uint32_t type, uint32_t size) {
        return {
            type,                                   // type
            size,                                   // length
            0,                                      // extra
            ZBI_FLAG_VERSION | ZBI_FLAG_CRC32,      // flags
            0,                                      // reserved0
            0,                                      // reserved1
            ZBI_ITEM_MAGIC,                         // magic
            0,                                      // crc32
        };
    }

    Item(const zbi_header_t& header, bool compress) :
        header_(header), compress_(compress) {
        if (compress_) {
            // We'll compress and checksum on the way out.
            header_.flags |= ZBI_FLAG_STORAGE_COMPRESSED;
        }
    }

    static ItemPtr MakeItem(const zbi_header_t& header,
                            bool compress = false) {
        return ItemPtr(new Item(header, compress));
    }

    void StreamRawPayload(OutputStream* out) {
        do {
            out->Write(payload_.front());
            payload_.pop_front();
        } while (!payload_.empty());
    }

    uint32_t StreamRaw(OutputStream* out) {
        // The header is already fully baked.
        out->Write(Iovec(&header_, sizeof(header_)));
        // The payload goes out as is.
        StreamRawPayload(out);
        return sizeof(header_) + header_.length;
    }

    uint32_t StreamCompressed(OutputStream* out) {
        // Compress and checksum the payload.
        Compressor compressor;
        compressor.Init(out, header_);
        do {
            // The compressor streams the header and compressed payload out.
            compressor.Write(out, payload_.front());
            payload_.pop_front();
        } while (!payload_.empty());
        // This writes the final header as well as the last of the payload.
        return compressor.Finish(out);
    }

    int ShowCmdline() const {
        std::string cmdline = std::accumulate(
            payload_.begin(), payload_.end(), std::string(),
            [](std::string cmdline, const iovec& iov) {
                return cmdline.append(
                    static_cast<const char*>(iov.iov_base),
                    iov.iov_len);
            });
        size_t start = 0;
        while (start < cmdline.size()) {
            size_t word_end = cmdline.find_first_of(kCmdlineWS, start);
            if (word_end == std::string::npos) {
                if (cmdline[start] != '\0') {
                    printf("        : %s\n", cmdline.c_str() + start);
                }
                break;
            }
            if (word_end > start) {
                printf("        : %.*s\n",
                       static_cast<int>(word_end - start),
                       cmdline.c_str() + start);
            }
            start = word_end + 1;
        }
        return 0;
    }

    const uint8_t* payload_data() {
        if (payload_.size() > 1) {
            AppendBuffer buffer(PayloadSize());
            for (const auto& iov : payload_) {
                buffer.Append(iov.iov_base, iov.iov_len);
            }
            payload_.clear();
            payload_.push_front(buffer.get());
            OwnBuffer(buffer.release());
        }
        assert(payload_.size() == 1);
        return static_cast<const uint8_t*>(payload_.front().iov_base);
    }

    class BootFSDirectoryIterator {
    public:
        operator bool() const {
            return left_ > 0;
        }

        const zbi_bootfs_dirent_t& operator*() const {
            auto entry = reinterpret_cast<const zbi_bootfs_dirent_t*>(next_);
            assert(left_ >= sizeof(*entry));
            return *entry;
        }

        const zbi_bootfs_dirent_t* operator->() const {
            return &**this;
        }

        BootFSDirectoryIterator& operator++() {
            assert(left_ > 0);
            if (left_ < sizeof(zbi_bootfs_dirent_t)) {
                fprintf(stderr, "BOOTFS directory truncated\n");
                left_ = 0;
            } else {
                size_t size = ZBI_BOOTFS_DIRENT_SIZE((*this)->name_len);
                if (size > left_) {
                    fprintf(stderr,
                            "BOOTFS directory truncated or bad name_len\n");
                    left_ = 0;
                } else {
                    next_ += size;
                    left_ -= size;
                }
            }
            return *this;
        }

        // The iterator itself is a container enough to use range-based for.
        const BootFSDirectoryIterator& begin() {
            return *this;
        }

        BootFSDirectoryIterator end() {
            return BootFSDirectoryIterator();
        }

        static int Create(Item* item, BootFSDirectoryIterator* it) {
            zbi_bootfs_header_t superblock;
            const uint32_t length = item->header_.length;
            if (length < sizeof(superblock)) {
                fprintf(stderr, "payload too short for BOOTFS header\n");
                return 1;
            }
            memcpy(&superblock, item->payload_data(), sizeof(superblock));
            if (superblock.magic != ZBI_BOOTFS_MAGIC) {
                fprintf(stderr, "BOOTFS header magic %#x should be %#x\n",
                        superblock.magic, ZBI_BOOTFS_MAGIC);
                return 1;
            }
            if (superblock.dirsize > length - sizeof(superblock)) {
                fprintf(stderr,
                        "BOOTFS header dirsize %u > payload size %zu\n",
                        superblock.dirsize, length - sizeof(superblock));
                return 1;
            }
            it->next_ = item->payload_data() + sizeof(superblock);
            it->left_ = superblock.dirsize;
            return 0;
        }

    private:
        const uint8_t* next_ = nullptr;
        uint32_t left_ = 0;
    };

    bool CheckBootFSDirent(const zbi_bootfs_dirent_t& entry,
                           bool always_print) const {
        const char* align_check =
            entry.data_off % ZBI_BOOTFS_PAGE_SIZE == 0 ? "" :
            "[ERROR: misaligned offset] ";
        const char* size_check =
            (entry.data_off < header_.length &&
             header_.length - entry.data_off >= entry.data_len) ? "" :
            "[ERROR: offset+size too large] ";
        bool ok = align_check[0] == '\0' && size_check[0] == '\0';
        if (always_print || !ok) {
            fprintf(always_print ? stdout : stderr,
                    "        : %08x %08x %s%s%.*s\n",
                    entry.data_off, entry.data_len,
                    align_check, size_check,
                    static_cast<int>(entry.name_len), entry.name);
        }
        return ok;
    }

    int ShowBootFS() {
        assert(!AlreadyCompressed());
        BootFSDirectoryIterator dir;
        int status = BootFSDirectoryIterator::Create(this, &dir);
        for (const auto& entry : dir) {
            if (!CheckBootFSDirent(entry, true)) {
                status = 1;
            }
        }
        return status;
    }

    class BootFSInputFileGenerator : public InputFileGenerator {
    public:
        explicit BootFSInputFileGenerator(ItemPtr item) :
            item_(std::move(item)) {
            if (item_->AlreadyCompressed()) {
                item_ = CreateFromCompressed(std::move(item_));
            }
            int status = BootFSDirectoryIterator::Create(item_.get(), &dir_);
            if (status != 0) {
                exit(status);
            }
        }

        ~BootFSInputFileGenerator() override = default;

        // Copying from an existing BOOTFS ignores the --prefix setting.
        bool Next(FileOpener*, const std::string&,
                  value_type* value) override {
            if (!dir_) {
                return false;
            }
            if (!item_->CheckBootFSDirent(*dir_, false)) {
                exit(1);
            }
            value->target = dir_->name;
            value->file = FileContents(*dir_, item_->payload_data());
            ++dir_;
            return true;
        }

    private:
        ItemPtr item_;
        BootFSDirectoryIterator dir_;
    };
};

constexpr decltype(Item::kItemTypes_) Item::kItemTypes_;

using ItemList = std::vector<ItemPtr>;

bool ImportFile(const FileContents& file, const char* filename,
                ItemList* items) {
    if (file.exact_size() <= (sizeof(zbi_header_t) * 2)) {
        return false;
    }
    const zbi_header_t* header = static_cast<const zbi_header_t*>(
        file.View(0, sizeof(zbi_header_t)).iov_base);
    if (!(header->type == ZBI_TYPE_CONTAINER &&
          header->extra == ZBI_CONTAINER_MAGIC &&
          header->magic == ZBI_ITEM_MAGIC)) {
        return false;
    }
    size_t file_size = file.exact_size() - sizeof(zbi_header_t);
    if (file_size != header->length) {
        fprintf(stderr, "%s: header size doesn't match file size\n", filename);
        exit(1);
    }
    if (!Aligned(header->length)) {
        fprintf(stderr, "ZBI item misaligned\n");
        exit(1);
    }
    uint32_t pos = sizeof(zbi_header_t);
    do {
        auto item = Item::CreateFromItem(file, pos);
        pos += item->TotalSize();
        items->push_back(std::move(item));
    } while (pos < file.exact_size());
    return true;
}

const uint32_t kImageArchUndefined = ZBI_TYPE_DISCARD;

// Returns nullptr if complete, else an explanatory string.
const char* IncompleteImage(const ItemList& items, const uint32_t image_arch) {
    if (!ZBI_IS_KERNEL_BOOTITEM(items.front()->type())) {
        return "first item not KERNEL";
    }

    if (items.front()->type() != image_arch &&
        image_arch != kImageArchUndefined) {
        return "kernel arch mismatch";
    }

    auto count =
        std::count_if(items.begin(), items.end(),
                      [](const ItemPtr& item) {
                          return item->type() == ZBI_TYPE_STORAGE_BOOTFS;
                      });
    if (count == 0) {
        return "no /boot BOOTFS item";
    }
    if (count > 1) {
        return "multiple BOOTFS items";
    }
    return nullptr;
}

constexpr const char kOptString[] = "-B:cd:e:FxXRg:hto:p:sT:uv";
constexpr const option kLongOpts[] = {
    {"complete", required_argument, nullptr, 'B'},
    {"compressed", no_argument, nullptr, 'c'},
    {"depfile", required_argument, nullptr, 'd'},
    {"entry", required_argument, nullptr, 'e'},
    {"files", no_argument, nullptr, 'F'},
    {"extract", no_argument, nullptr, 'x'},
    {"extract-items", no_argument, nullptr, 'X'},
    {"extract-raw", no_argument, nullptr, 'R'},
    {"groups", required_argument, nullptr, 'g'},
    {"help", no_argument, nullptr, 'h'},
    {"list", no_argument, nullptr, 't'},
    {"output", required_argument, nullptr, 'o'},
    {"prefix", required_argument, nullptr, 'p'},
    {"sort", no_argument, nullptr, 's'},
    {"type", required_argument, nullptr, 'T'},
    {"uncompressed", no_argument, nullptr, 'u'},
    {"verbose", no_argument, nullptr, 'v'},
    {nullptr, no_argument, nullptr, 0},
};

constexpr const char kUsageFormatString[] = "\
Usage: %s [OUTPUT...] INPUT... [-- PATTERN...]\n\
\n\
Diagnostic switches:\n\
    --help, -h                     print this message\n\
    --list, -t                     list input ZBI item headers; no --output\n\
    --verbose, -v                  show contents (e.g. BOOTFS file names)\n\
    --extract, -x                  extract BOOTFS files\n\
    --extract-items, -X            extract items as pseudo-files (see below)\n\
    --extract-raw, -R              extract original payloads, not ZBI format\n\
\n\
Output file switches must come before input arguments:\n\
    --output=FILE, -o FILE         output file name\n\
    --depfile=FILE, -d FILE        makefile dependency output file name\n\
\n\
The `--output` FILE is always removed and created fresh after all input\n\
files have been opened.  So it is safe to use the same file name as an input\n\
file and the `--output` FILE, to append more items.\n\
\n\
Input control switches apply to subsequent input arguments:\n\
    --files, -F                    read BOOTFS manifest files (default)\n\
    --groups=GROUPS, -g GROUPS     comma-separated list of manifest groups\n\
    --prefix=PREFIX, -p PREFIX     prepend PREFIX/ to target file names\n\
    --type=TYPE, -T TYPE           input files are TYPE items (see below)\n\
    --compressed, -c               compress RAMDISK images (default)\n\
    --uncompressed, -u             do not compress RAMDISK images\n\
\n\
Input arguments:\n\
    --entry=TEXT, -e  TEXT         like an input file containing only TEXT\n\
    FILE                           input or manifest file\n\
    DIRECTORY                      directory tree copied to BOOTFS PREFIX/\n\
\n\
With `--files` or `-F` (the default state), files with ZBI_TYPE_CONTAINER\n\
headers are incomplete boot files and other files are BOOTFS manifest files.\n\
Each DIRECTORY is listed recursively and handled just like a manifest file\n\
using the path relative to DIRECTORY as the target name (before any PREFIX).\n\
Each `--group`, `--prefix`, `-g`, or `-p` switch affects each file from a\n\
manifest or directory in subsequent FILE or DIRECTORY arguments.\n\
\n\
With `--type` or `-T`, input files are treated as TYPE instead of manifest\n\
files, and directories are not permitted.  See below for the TYPE strings.\n\
\n\
Format control switches (last switch affects all output):\n\
    --complete=ARCH, -B ARCH       verify result is a complete boot image\n\
    --compressed, -c               compress BOOTFS images (default)\n\
    --uncompressed, -u             do not compress BOOTFS images\n\
    --sort, -s                     sort BOOTFS entries by name\n\
\n\
In all cases there is only a single BOOTFS item (if any) written out.\n\
The BOOTFS image contains all files from BOOTFS items in ZBI input files,\n\
manifest files, directories, and `--entry` switches (in input order unless\n\
`--sort` was specified).\n\
\n\
Arguments after -- are shell filename patterns (* matches even /)\n\
to filter the files that will be packed into BOOTFS, extracted, or listed.\n\
\n\
When extracting a single file, `--output` or `-o` can be used.\n\
Otherwise multiple files are created with their BOOTFS file names\n\
relative to PREFIX (default empty, so in the current directory).\n\
\n\
With `--extract-items` or `-X`, instead of BOOTFS files the names are\n\
synthesized as shown below, numbered in the order items appear in the input\n\
starting with 001.  Output files are ZBI files that can be input later.\n\
\n\
With `--extract-raw` or `-R`, each file is written with just the\n\
uncompressed payload of the item and no ZBI headers.\n\
\n\
";

void usage(const char* progname) {
    fprintf(stderr, kUsageFormatString, progname);
    Item::PrintTypeUsage(stderr);
}

}  // anonymous namespace

int main(int argc, char** argv) {
    FileOpener opener;
    GroupFilter filter;
    const char* outfile = nullptr;
    const char* depfile = nullptr;
    uint32_t complete_arch = kImageArchUndefined;
    bool input_manifest = true;
    uint32_t input_type = ZBI_TYPE_DISCARD;
    bool compressed = true;
    bool extract = false;
    bool extract_items = false;
    bool extract_raw = false;
    bool list_contents = false;
    bool sort = false;
    bool verbose = false;
    ItemList items;
    InputFileGeneratorList bootfs_input;
    std::string prefix;
    int opt;
    while ((opt = getopt_long(argc, argv,
                              kOptString, kLongOpts, nullptr)) != -1) {
        // A non-option argument (1) is an input, handled below.
        // All other cases continue the loop and don't break the switch.
        switch (opt) {
        case 1:
            break;

        case 'o':
            if (outfile) {
                fprintf(stderr, "only one output file\n");
                exit(1);
            }
            if (!items.empty()) {
                fprintf(stderr, "--output or -o must precede inputs\n");
                exit(1);
            }
            outfile = optarg;
            continue;

        case 'd':
            if (depfile) {
                fprintf(stderr, "only one depfile\n");
                exit(1);
            }
            if (!outfile) {
                fprintf(stderr,
                        "--output -or -o must precede --depfile or -d\n");
                exit(1);
            }
            if (!items.empty()) {
                fprintf(stderr, "--depfile or -d must precede inputs\n");
                exit(1);
            }
            opener.Init(outfile, depfile);
            continue;

        case 'F':
            input_manifest = true;
            continue;

        case 'T':
            if (Item::ParseTypeName(optarg, &input_type)) {
                input_manifest = false;
            } else {
                fprintf(stderr, "unrecognized type: %s\n", optarg);
                exit(1);
            }
            continue;

        case 'p':
            // A nonempty prefix should have no leading slashes and
            // exactly one trailing slash.
            prefix = optarg;
            while (!prefix.empty() && prefix.front() == '/') {
                prefix.erase(0, 1);
            }
            if (!prefix.empty() && prefix.back() == '/') {
                prefix.pop_back();
            }
            if (prefix.empty() && optarg[0] != '\0') {
                fprintf(stderr, "\
--prefix cannot be /; use --prefix= (empty) instead\n");
                exit(1);
            }
            if (!prefix.empty()) {
                prefix.push_back('/');
            }
            continue;

        case 'g':
            filter.SetFilter(optarg);
            continue;

        case 't':
            list_contents = true;
            continue;

        case 'v':
            verbose = true;
            continue;

        case 'B':
            if (!strcmp(optarg, "x64")) {
                complete_arch = ZBI_TYPE_KERNEL_X64;
            } else if (!strcmp(optarg, "arm64")) {
                complete_arch = ZBI_TYPE_KERNEL_ARM64;
            } else {
                fprintf(stderr, "--complete architecture argument must be one"
                        " of: x64, arm64\n");
                exit(1);
            }
            continue;
        case 'c':
            compressed = true;
            continue;

        case 'u':
            compressed = false;
            continue;

        case 's':
            sort = true;
            continue;

        case 'x':
            extract = true;
            continue;

        case 'X':
            extract = true;
            extract_items = true;
            continue;

        case 'R':
            extract = true;
            extract_items = true;
            extract_raw = true;
            continue;

        case 'e':
            if (input_manifest) {
                bootfs_input.emplace_back(
                    new ManifestInputFileGenerator(FileContents(optarg, false),
                                                   prefix, &filter));
            } else if (input_type == ZBI_TYPE_CONTAINER) {
                fprintf(stderr,
                        "cannot use --entry (-e) with --target=CONTAINER\n");
                exit(1);
            } else {
                items.push_back(
                    Item::CreateFromFile(
                        FileContents(optarg, input_type == ZBI_TYPE_CMDLINE),
                        input_type, compressed));
            }
            continue;

        case 'h':
        default:
            usage(argv[0]);
            exit(opt == 'h' ? 0 : 1);
        }
        assert(opt == 1);

        struct stat st;
        auto fd = opener.Open(optarg, &st);

        // A directory populates the BOOTFS.
        if (input_manifest && S_ISDIR(st.st_mode)) {
            // Calculate the prefix for opening files within the directory.
            // This won't be part of the BOOTFS file name.
            std::string dir_prefix(optarg);
            if (dir_prefix.back() != '/') {
                dir_prefix.push_back('/');
            }
            bootfs_input.emplace_back(
                new DirectoryInputFileGenerator(std::move(fd),
                                                std::move(dir_prefix)));
            continue;
        }

        // Anything else must be a regular file.
        RequireRegularFile(st, optarg);
        auto file = FileContents::Map(std::move(fd), st, optarg);

        if (input_manifest || input_type == ZBI_TYPE_CONTAINER) {
            if (ImportFile(file, optarg, &items)) {
                // It's another file in ZBI format.  The last item will own
                // the file buffer, so it lives until all earlier items are
                // exhausted.
                items.back()->OwnFile(std::move(file));
            } else if (input_manifest) {
                // It must be a manifest file.
                bootfs_input.emplace_back(
                    new ManifestInputFileGenerator(std::move(file),
                                                   prefix, &filter));
            } else {
                fprintf(stderr, "%s: not a Zircon Boot container\n", optarg);
                exit(1);
            }
        } else {
            items.push_back(Item::CreateFromFile(std::move(file),
                                                 input_type, compressed));
        }
    }

    // Remaining arguments (after --) are patterns for matching file names.
    NameMatcher name_matcher(argv, optind, argc);

    if (list_contents) {
        if (outfile || depfile) {
            fprintf(stderr, "\
--output (-o) and --depfile (-d) are incompatible with --list (-t)\n");
            exit(1);
        }
    } else {
        if (!outfile && !extract) {
            fprintf(stderr, "no output file\n");
            exit(1);
        }
    }

    // Don't merge incoming items when only listing or extracting.
    const bool merge = !list_contents && !extract;

    auto is_bootfs = [](const ItemPtr& item) {
        return item->type() == ZBI_TYPE_STORAGE_BOOTFS;
    };

    // If there are multiple BOOTFS input items, or any BOOTFS items when
    // we're also creating a fresh BOOTFS, merge them all into the new one.
    const bool merge_bootfs =
        ((!extract_items && !name_matcher.MatchesAll()) ||
         ((merge || !bootfs_input.empty()) &&
          ((bootfs_input.empty() ? 0 : 1) +
           std::count_if(items.begin(), items.end(), is_bootfs)) > 1));

    if (merge_bootfs) {
        for (auto& item : items) {
            if (is_bootfs(item)) {
                // Null out the list entry.
                ItemPtr old;
                item.swap(old);
                // The generator consumes the old item.
                bootfs_input.push_back(Item::ReadBootFS(std::move(old)));
            }
        }
    }

    ItemPtr keepalive;
    if (merge) {
        // Merge multiple CMDLINE input items with spaces in between.
        std::string cmdline;
        for (auto& item : items) {
            if (item && item->type() == ZBI_TYPE_CMDLINE) {
                // Null out the list entry.
                ItemPtr old;
                item.swap(old);
                cmdline.append({' '});
                old->AppendPayload(&cmdline);
                // Trim leading whitespace.
                cmdline.erase(0, cmdline.find_first_not_of(kCmdlineWS));
                // Trim trailing NULs and whitespace.
                while (!cmdline.empty() && cmdline.back() == '\0') {
                    cmdline.pop_back();
                }
                cmdline.erase(cmdline.find_last_not_of(kCmdlineWS) + 1);
                // Keep alive all the owned files from the old item,
                // since it might have owned files used by other items.
                old->TakeOwned(std::move(keepalive));
                keepalive.swap(old);
            }
        }
        if (!cmdline.empty()) {
            size_t size = cmdline.size() + 1;
            auto buffer = std::make_unique<uint8_t[]>(size);
            memcpy(buffer.get(), cmdline.c_str(), size);
            items.push_back(Item::CreateFromBuffer(ZBI_TYPE_CMDLINE,
                                                   std::move(buffer), size));
        }
    }

    // Compact out the null entries.
    items.erase(std::remove(items.begin(), items.end(), nullptr), items.end());

    if (!bootfs_input.empty()) {
        // Pack up the BOOTFS.
        items.push_back(
            Item::CreateBootFS(&opener, bootfs_input, [&](const char* name) {
                    return extract_items || name_matcher.Matches(name);
                }, sort, prefix, compressed));
    }

    if (items.empty()) {
        fprintf(stderr, "no inputs\n");
        exit(1);
    }

    items.back()->TakeOwned(std::move(keepalive));

    if (!list_contents && complete_arch != kImageArchUndefined) {
        // The only hard requirement is that the kernel be first.
        // But it seems most orderly to put the BOOTFS second,
        // other storage in the middle, and CMDLINE last.
        std::stable_sort(
            items.begin(), items.end(),
            [](const ItemPtr& a, const ItemPtr& b) {
                auto item_rank = [](uint32_t type) {
                    return (ZBI_IS_KERNEL_BOOTITEM(type) ? 0 :
                            type == ZBI_TYPE_STORAGE_BOOTFS ? 1 :
                            type == ZBI_TYPE_CMDLINE ? 9 :
                            5);
                };
                return item_rank(a->type()) < item_rank(b->type());
            });
    }

    if (complete_arch != kImageArchUndefined) {
        const char* incomplete = IncompleteImage(items, complete_arch);
        if (incomplete) {
            fprintf(stderr, "incomplete image: %s\n", incomplete);
            exit(1);
        }
    }

    // Now we're ready to start writing output!
    FileWriter writer(outfile, std::move(prefix));

    if (list_contents || verbose || extract) {
        if (list_contents || verbose) {
            const char* incomplete = IncompleteImage(items, complete_arch);
            if (incomplete) {
                printf("INCOMPLETE: %s\n", incomplete);
            } else {
                puts("COMPLETE: bootable image");
            }
        }

        // Contents start after the ZBI_TYPE_CONTAINER header.
        uint32_t pos = sizeof(zbi_header_t);
        int status = 0;
        for (auto& item : items) {
            if (list_contents || verbose) {
                item->Describe(pos);
            }
            if (verbose) {
                status |= item->Show();
            }
            pos += item->TotalSize();
            if (extract_items) {
                if (extract_raw) {
                    item->ExtractRaw(&writer, &name_matcher);
                } else {
                    item->ExtractItem(&writer, &name_matcher);
                }
            } else if (extract && is_bootfs(item)) {
                auto generator = Item::ReadBootFS(std::move(item));
                InputFileGenerator::value_type next;
                while (generator->Next(&opener, prefix, &next)) {
                    if (name_matcher.Matches(next.target.c_str())) {
                        writer.RawFile(next.target.c_str())
                            .Write(next.file.View(0, next.file.exact_size()));
                    }
                }
            }
        }
        if (status) {
            exit(status);
        }
    } else {
        Item::WriteZBI(&writer, "boot.zbi", items);
    }

    name_matcher.Summary(extract ? "extracted" : "matched",
                         extract_items ? "boot items" : "BOOTFS files",
                         verbose);

    return 0;
}
