// 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 <cstring>

#ifdef __Fuchsia__
#include <fuchsia/hardware/block/volume/c/fidl.h>
#endif

#include <fvm/format.h>

#include <zircon/assert.h>

namespace fvm {
namespace {

// Used to check whether a given VPartitionEntry is flagged as an inactive partition.
// This flags are a mirror of those exposed in the fidl interface. Since this code is used in host
// too, we can't rely on them directly, but enforce compile time checks that the values match.
constexpr uint32_t kVPartitionEntryFlagMask = 0x00000001;
constexpr uint32_t kVPartitionEntryFlagInactive = 0x00000001;

#ifdef __Fuchsia__
// Enforce target and host flags to match.
static_assert(kVPartitionEntryFlagInactive ==
                  fuchsia_hardware_block_volume_AllocatePartitionFlagInactive,
              "Inactive Flag must match FIDL definition.");
#endif

// Slice Entry mask for retrieving the assigned partition.
constexpr uint64_t kVPartitionEntryMax = (1ull << kSliceEntryVPartitionBits) - 1;
constexpr uint64_t kVPartitionEntryMask = kVPartitionEntryMax;

static_assert(kMaxVPartitions <= kVPartitionEntryMax,
              "VPartition addres space needs to fit within Slice Entry VPartitionBits.");

// Slice Entry mask for retrieving the assigned vslice.
constexpr uint64_t kSliceEntryVSliceMax = (1ull << kSliceEntryVSliceBits) - 1;
constexpr uint64_t kSliceEntryVSliceMask = kSliceEntryVSliceMax << kSliceEntryVPartitionBits;

static_assert(kSliceEntryVSliceMax >= fvm::kMaxVSlices,
              "SliceEntry must be able to address the range [0. kMaxVSlice)");

// Remaining bits.
constexpr uint64_t kSliceEntryReservedBits = 16;

static_assert(kSliceEntryVPartitionBits + kSliceEntryVSliceBits + kSliceEntryReservedBits == 64,
              "Exceeding SliceEntry payload size.");

} // namespace

VPartitionEntry VPartitionEntry::Create(const uint8_t* type, const uint8_t* guid, uint32_t slices,
                                        const char* name, uint32_t flags) {
    VPartitionEntry entry = VPartitionEntry::Create();
    entry.slices = slices;
    // Filter out unallowed flags.
    entry.flags = ParseFlags(flags);
    memcpy(&entry.type, type, kGuidSize);
    memcpy(&entry.guid, guid, kGuidSize);
    memcpy(&entry.name, name, kMaxVPartitionNameLength);
    return entry;
}

uint32_t VPartitionEntry::ParseFlags(uint32_t raw_flags) {
    return raw_flags & kVPartitionEntryFlagMask;
}

bool VPartitionEntry::IsActive() const {
    return (flags & kVPartitionEntryFlagInactive) == 0;
}

bool VPartitionEntry::IsInactive() const {
    return !IsActive();
}

bool VPartitionEntry::IsAllocated() const {
    return slices != 0;
}

bool VPartitionEntry::IsFree() const {
    return !IsAllocated();
}

void VPartitionEntry::Release() {
    memset(this, 0, sizeof(VPartitionEntry));
    ZX_DEBUG_ASSERT_MSG(IsFree(),
                        "VPartitionEntry must be free after calling VPartitionEntry::Release()");
}

void VPartitionEntry::SetActive(bool is_active) {
    if (is_active) {
        flags &= (~kVPartitionEntryFlagInactive);
    } else {
        flags |= kVPartitionEntryFlagInactive;
    }
}

SliceEntry SliceEntry::Create(uint64_t vpartition, uint64_t vslice) {
    SliceEntry entry;
    entry.Set(vpartition, vslice);
    return entry;
}

void SliceEntry::Set(uint64_t vpartition, uint64_t vslice) {
    ZX_DEBUG_ASSERT(vpartition < kVPartitionEntryMax);
    ZX_DEBUG_ASSERT(vslice < kSliceEntryVSliceMax);
    data = 0ull | (vpartition & kVPartitionEntryMax) |
           ((vslice & kSliceEntryVSliceMax) << (kSliceEntryVPartitionBits));
}

void SliceEntry::Release() {
    data = 0;
}

bool SliceEntry::IsAllocated() const {
    return VPartition() != 0;
}

bool SliceEntry::IsFree() const {
    return !IsAllocated();
}

uint64_t SliceEntry::VSlice() const {
    uint64_t vslice = (data & kSliceEntryVSliceMask) >> kSliceEntryVPartitionBits;
    ZX_DEBUG_ASSERT_MSG(vslice < (1ul << kSliceEntryVSliceBits),
                        "Slice assigned to vslice out of range.");
    return vslice;
}

uint64_t SliceEntry::VPartition() const {
    uint64_t vpartition = (data & kVPartitionEntryMask);
    ZX_DEBUG_ASSERT_MSG(vpartition < kMaxVPartitions, "Slice assigned to Partition out of range.");
    return vpartition;
}

} // namespace fvm
