// Copyright 2019 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 <lib/inspect-vmo/block.h>
#include <lib/inspect-vmo/snapshot.h>

namespace inspect {
namespace vmo {

using internal::Block;

Snapshot::Snapshot(fbl::Array<uint8_t> buffer)
    : buffer_(std::move(buffer)) {}

zx_status_t Snapshot::Create(const zx::vmo& vmo, Snapshot* out_snapshot) {
    return Snapshot::Create(std::move(vmo), kDefaultOptions, out_snapshot);
}

zx_status_t Snapshot::Create(const zx::vmo& vmo, Options options, Snapshot* out_snapshot) {
    return Snapshot::Create(std::move(vmo), std::move(options), nullptr, out_snapshot);
}

zx_status_t Snapshot::Create(const zx::vmo& vmo, Options options, ReadObserver read_observer,
                             Snapshot* out_snapshot) {
    size_t tries_left = options.read_attempts;

    zx_status_t status;
    fbl::Array<uint8_t> buffer;

    while (tries_left-- > 0) {
        size_t size;
        status = vmo.get_size(&size);
        if (status != ZX_OK) {
            return status;
        }
        if (size < sizeof(internal::Block)) {
            return ZX_ERR_OUT_OF_RANGE;
        }
        if (buffer.size() != size) {
            buffer.reset(new uint8_t[size], size);
        }

        status = Snapshot::Read(vmo, sizeof(internal::Block), buffer.begin());
        if (status != ZX_OK) {
            return status;
        }
        if (read_observer) {
            read_observer(buffer.begin(), sizeof(internal::Block));
        }

        uint64_t generation;
        status = Snapshot::ParseHeader(buffer.begin(), &generation);
        if (status != ZX_OK) {
            return status;
        }

        if (!options.skip_consistency_check && generation % 2 != 0) {
            continue;
        }

        status = Snapshot::Read(vmo, size, buffer.begin());
        if (status != ZX_OK) {
            return status;
        }
        if (read_observer) {
            read_observer(buffer.begin(), sizeof(size));
        }

        uint64_t new_generation;
        status = Snapshot::ParseHeader(buffer.begin(), &new_generation);
        if (status != ZX_OK) {
            return status;
        }
        if (!options.skip_consistency_check && generation != new_generation) {
            continue;
        }

        size_t new_size;
        if (vmo.get_size(&new_size) != ZX_OK) {
            return ZX_ERR_INTERNAL;
        }
        if (new_size != size) {
            continue;
        }

        *out_snapshot = Snapshot(std::move(buffer));

        return ZX_OK;
    }

    return ZX_ERR_INTERNAL;
}

zx_status_t Snapshot::Read(const zx::vmo& vmo, size_t size, uint8_t* buffer) {
    memset(buffer, 0, size);
    return vmo.read(buffer, 0, size);
}

zx_status_t Snapshot::ParseHeader(uint8_t* buffer, uint64_t* out_generation_count) {
    Block* block = reinterpret_cast<Block*>(buffer);
    if (memcmp(&block->header_data[4], kMagicNumber, 4) != 0) {
        return ZX_ERR_INTERNAL;
    }
    *out_generation_count = block->payload.u64;
    return ZX_OK;
}

internal::Block* Snapshot::GetBlock(internal::BlockIndex index) const {
    if (index >= IndexForOffset(buffer_.size())) {
        return nullptr;
    }
    return reinterpret_cast<internal::Block*>(buffer_.begin() + index * kMinOrderSize);
}

} // namespace vmo
} // namespace inspect
