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

#pragma once

#include <fbl/algorithm.h>
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <zircon/assert.h>

#include <type_traits>

namespace hwreg {

struct EnablePrinter;

namespace internal {

template <typename T> struct IsSupportedInt : std::false_type {};
template <> struct IsSupportedInt<uint8_t> : std::true_type {};
template <> struct IsSupportedInt<uint16_t> : std::true_type {};
template <> struct IsSupportedInt<uint32_t> : std::true_type {};
template <> struct IsSupportedInt<uint64_t> : std::true_type {};

template <class IntType> constexpr IntType ComputeMask(uint32_t num_bits) {
    if (num_bits == sizeof(IntType) * CHAR_BIT) {
        return static_cast<IntType>(~0ull);
    }
    return static_cast<IntType>((static_cast<IntType>(1) << num_bits) - 1);
}

class FieldPrinter {
public:
    constexpr FieldPrinter() : name_(nullptr), bit_high_incl_(0), bit_low_(0) {
    }
    constexpr FieldPrinter(const char* name, uint32_t bit_high_incl, uint32_t bit_low)
        : name_(name), bit_high_incl_(bit_high_incl), bit_low_(bit_low) {
    }

    // Prints the field name, and the result of extracting the field from |value| in
    // hex (with a left-padding of zeroes to a length matching the maximum number of
    // nibbles needed to represent any value the field could take).
    void Print(uint64_t value, char* buf, size_t len) const;

private:
    const char* name_;
    uint32_t bit_high_incl_;
    uint32_t bit_low_;
};

// Structure used to reduce the storage cost of the pretty-printing features if
// they are not enabled.
template <typename T, typename IntType> struct FieldPrinterList {
    void AppendField(const char* name, uint32_t bit_high_incl, uint32_t bit_low) {
    }
};

template <typename IntType> struct FieldPrinterList<EnablePrinter, IntType> {
    // These two members are used for implementing the Print() function above.
    // They will typically be optimized away if Print() is not used.
    FieldPrinter fields[sizeof(IntType) * CHAR_BIT];
    unsigned num_fields = 0;

    void AppendField(const char* name, uint32_t bit_high_incl, uint32_t bit_low) {
        ZX_DEBUG_ASSERT(num_fields < fbl::count_of(fields));
        fields[num_fields++] = FieldPrinter(name, bit_high_incl, bit_low);
    }
};

// Used to record information about a field at construction time.  This enables
// checking for overlapping fields and pretty-printing.
template <class RegType> class Field {
private:
    using IntType = typename RegType::ValueType;
public:
    Field(RegType* reg, const char* name, uint32_t bit_high_incl, uint32_t bit_low) {
        IntType mask = static_cast<IntType>(
                internal::ComputeMask<IntType>(bit_high_incl - bit_low + 1) << bit_low);
        // Check for overlapping bit ranges
        ZX_DEBUG_ASSERT((reg->fields_mask_ & mask) == 0ull);
        reg->fields_mask_ = static_cast<IntType>(reg->fields_mask_ | mask);

        reg->printer_.AppendField(name, bit_high_incl, bit_low);
    }
};

// Used to record information about reserved-zero fields at construction time.
// This enables auto-zeroing of reserved-zero fields on register write.
// Represents a field that must be zeroed on write.
template <class RegType> class RsvdZField {
private:
    using IntType = typename RegType::ValueType;
public:
    RsvdZField(RegType* reg, uint32_t bit_high_incl, uint32_t bit_low) {
        IntType mask = static_cast<IntType>(
                internal::ComputeMask<IntType>(bit_high_incl - bit_low + 1) << bit_low);
        reg->rsvdz_mask_ = static_cast<IntType>(reg->rsvdz_mask_ | mask);
    }
};

// Implementation for RegisterBase::Print, see the documentation there.
// |reg_value| is the current value of the register.
// |fields_mask| is a bitmask with a bit set for each bit that has been defined
// in the register.
template <typename F>
void PrintRegister(F print_fn,
                   FieldPrinter fields[], size_t num_fields,
                   uint64_t reg_value, uint64_t fields_mask,
                   int register_width_bytes) {
    char buf[128];
    for (unsigned i = 0; i < num_fields; ++i) {
        fields[i].Print(reg_value, buf, sizeof(buf));
        print_fn(buf);
    }

    // Check if any unknown bits are set, and if so let the caller know
    uint64_t val = reg_value & ~fields_mask;
    if (val != 0) {
        int pad_len = (register_width_bytes * CHAR_BIT) / 4;
        snprintf(buf, sizeof(buf), "unknown set bits: 0x%0*" PRIx64, pad_len, val);
        buf[sizeof(buf) - 1] = 0;
        print_fn(buf);
    }
}

// Utility for the common print function of [](const char* arg) { printf("%s\n", arg); }
void PrintRegisterPrintf(FieldPrinter fields[], size_t num_fields,
                         uint64_t reg_value, uint64_t fields_mask,
                         int register_width_bytes);

} // namespace internal

} // namespace hwreg
