// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "mpact/sim/decoder/format.h"

#include <algorithm>
#include <cstdint>
#include <string>
#include <utility>

#include "absl/numeric/bits.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "antlr4-runtime/Token.h"
#include "mpact/sim/decoder/format_name.h"
#include "mpact/sim/decoder/overlay.h"

namespace mpact {
namespace sim {
namespace decoder {
namespace bin_format {

using ::mpact::sim::machine_description::instruction_set::ToSnakeCase;

FieldOrFormat::~FieldOrFormat() {
  if (is_field_) {
    delete field_;
  }
  field_ = nullptr;
  format_ = nullptr;
}

// The equality operator compares to verify that the field/format definitions
// are equivalent, i.e., refers to the same bits.
bool FieldOrFormat::operator==(const FieldOrFormat& rhs) const {
  if (is_field_ != rhs.is_field_) return false;
  if (is_field_) {
    if (high_ != rhs.high_) return false;
    if (size_ != rhs.size_) return false;
  } else {
    if (format_ != rhs.format_) return false;
  }
  return true;
}

bool FieldOrFormat::operator!=(const FieldOrFormat& rhs) const {
  return !(*this == rhs);
}

using ::mpact::sim::machine_description::instruction_set::ToPascalCase;

Format::Format(std::string name, int width, BinEncodingInfo* encoding_info)
    : Format(name, width, "", encoding_info) {}

Format::Format(std::string name, int width, std::string base_format_name,
               BinEncodingInfo* encoding_info)
    : name_(name),
      base_format_name_(base_format_name),
      declared_width_(width),
      encoding_info_(encoding_info) {}

Format::~Format() {
  // for (auto &[unused, field_ptr] : field_map_) {
  //   delete field_ptr;
  // }
  field_map_.clear();
  for (auto& [unused, overlay_ptr] : overlay_map_) {
    delete overlay_ptr;
  }
  overlay_map_.clear();
  for (auto* field : field_vec_) {
    delete field;
  }
  field_vec_.clear();
}

// Add a field to the current format with the given width and signed/unsigned
// attribute.
absl::Status Format::AddField(std::string name, bool is_signed, int width) {
  // Make sure that the name isn't used already in the format.
  if (field_map_.contains(name)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Field '", name, "' already defined"));
  }
  auto field = new Field(name, is_signed, width, this);
  field_vec_.push_back(new FieldOrFormat(field));
  field_map_.insert(std::make_pair(name, field));
  return absl::OkStatus();
}

// Add a format reference field - name of another format - to the current
// format. This will be resolved once all the formats have been parsed.
void Format::AddFormatReferenceField(std::string format_alias,
                                     std::string format_name, int size,
                                     antlr4::Token* ctx) {
  field_vec_.push_back(new FieldOrFormat(format_alias, format_name, size, ctx));
}

// Add an overlay to the current format. An overlay is a named alias for a
// not necessarily contiguous nor in order collection of bits in the format.
absl::StatusOr<Overlay*> Format::AddFieldOverlay(std::string name,
                                                 bool is_signed, int width) {
  // Make sure that the name isn't used already in the format.
  if (overlay_map_.contains(name)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Overlay '", name, "' already defined as an overlay"));
  }
  if (field_map_.contains(name)) {
    return absl::InvalidArgumentError(
        absl::StrCat("Overlay '", name, "' already defined as a field"));
  }
  auto overlay = new Overlay(name, is_signed, width, this);
  overlay_map_.insert(std::make_pair(name, overlay));
  return overlay;
}

// Return the named field if it exists, nullptr otherwise.
Field* Format::GetField(absl::string_view field_name) const {
  auto iter = field_map_.find(field_name);
  if (iter == field_map_.end()) return nullptr;
  return iter->second;
}

// Return the named field if it exists, nullptr otherwise.
Overlay* Format::GetOverlay(absl::string_view overlay_name) const {
  auto iter = overlay_map_.find(overlay_name);
  if (iter == overlay_map_.end()) return nullptr;
  return iter->second;
}

// Return the string containing the integer type used to contain the current
// format. If it is greater than 128 bits, will use a byte array (int8_t *).
// If it is 65 to 128 bits, will use absl::[u]int128.
std::string Format::GetUIntType(int bitwidth) const {
  if (bitwidth > 128) return "uint8_t *";
  if (bitwidth > 64) return "absl::uint128";
  return absl::StrCat("uint", GetIntTypeBitWidth(bitwidth), "_t");
}

std::string Format::GetIntType(int bitwidth) const {
  if (bitwidth > 128) return "int8_t *";
  if (bitwidth > 64) return "absl::int128";
  return absl::StrCat("int", GetIntTypeBitWidth(bitwidth), "_t");
}

// Return the int type byte width (1, 2, 4, 8, 16) or (-1 if it's bigger), of
// the integer type that would fit this format.
int Format::GetIntTypeBitWidth(int bitwidth) const {
  auto shift = absl::bit_width(static_cast<unsigned>(bitwidth)) - 1;
  if (absl::popcount(static_cast<unsigned>(bitwidth)) > 1) shift++;
  shift = std::max(shift, 3);
  if (shift > 7) return -1;
  return 1 << shift;
}

// Once all the formats have been read in, this method is called to check the
// format and update any widths that depended on other formats being read in.
absl::Status Format::ComputeAndCheckFormatWidth() {
  // If there is a base format name, look up that format, verify that the widths
  // are the same.
  if (!base_format_name_.empty()) {
    auto* base_format = encoding_info_->GetFormat(base_format_name_);
    if (base_format == nullptr) {
      return absl::InternalError(
          absl::StrCat("Format ", name(), " refers to undefined base format ",
                       base_format_name_));
    }
    if (base_format->declared_width() != declared_width_) {
      return absl::InternalError(absl::StrCat(
          "Format ", name_, " (", declared_width_,
          ") differs in width from base format ", base_format->name(), " (",
          base_format->declared_width(), ")"));
    }
    base_format_ = base_format;
    base_format_->derived_formats_.push_back(this);
  }
  if (computed_width_ == 0) {
    // Go through the list of fields/format references. Get the declared widths
    // of the formats and add to the computed width. Signal error if the
    // computed width differs from the declared width.
    for (auto* field_or_format : field_vec_) {
      // Field.
      if (field_or_format->is_field()) {
        auto* field = field_or_format->field();
        field->high = declared_width_ - computed_width_ - 1;
        field->low = field->high - field->width + 1;
        computed_width_ += field->width;
        extractors_.insert(std::make_pair(field->name, field_or_format));
        continue;
      }

      // Format;
      auto* format = field_or_format->format();
      if (format == nullptr) {
        std::string fmt_name = field_or_format->format_name();
        format = encoding_info_->GetFormat(fmt_name);
        if (format == nullptr) {
          return absl::InternalError(absl::StrCat(
              "Format '", name(), "' refers to undefined format ", fmt_name));
        }
        field_or_format->set_format(format);
      }
      field_or_format->set_high(declared_width_ - computed_width_ - 1);
      computed_width_ += format->declared_width() * field_or_format->size();
      extractors_.insert(
          std::make_pair(field_or_format->format_alias(), field_or_format));
    }
    if (computed_width_ != declared_width_) {
      return absl::InternalError(absl::StrCat(
          "Format '", name_, "' declared width (", declared_width_,
          ") differs from computed width (", computed_width_, ")"));
    }
  }
  for (auto& [name, overlay_ptr] : overlay_map_) {
    auto status = overlay_ptr->ComputeHighLow();
    if (!status.ok()) return status;
    overlay_extractors_.insert(std::make_pair(name, overlay_ptr));
  }
  // Set the type names.
  int_type_name_ = GetIntType(declared_width_);
  uint_type_name_ = absl::StrCat("u", int_type_name_);
  return absl::OkStatus();
}

// The extractor functions in the generated code are all generated within a
// namespace specific to the format they're associated with. However, extractors
// that don't conflict in the bits they select may be promoted to be generated
// in the base format namespace. This method is used to propagate such
// potential promotions upward in the inheritance tree.
void Format::PropagateExtractorsUp() {
  for (auto* fmt : derived_formats_) {
    fmt->PropagateExtractorsUp();
  }
  if (base_format_ != nullptr) {
    // Try to propagate extractors up the inheritance tree.
    for (auto const& [name, field_or_format_ptr] : extractors_) {
      // Ignore those that have a nullptr, they have already failed to be
      // promoted.
      if (field_or_format_ptr == nullptr) continue;
      auto iter = base_format_->extractors_.find(name);
      // If it isn't in the parent, add it.
      if (iter == base_format_->extractors_.end()) {
        base_format_->extractors_.insert(
            std::make_pair(name, field_or_format_ptr));
      } else if (iter->second == nullptr) {
        // Can't promote it, a previous attempt failed.
        continue;
      } else if (*field_or_format_ptr != *(iter->second)) {
        // If the base extractor refers to a different object, fail the
        // promotion.
        base_format_->extractors_[name] = nullptr;
      }
    }
    for (auto const& [name, overlay_ptr] : overlay_extractors_) {
      // Ignore those that have a nullptr, they have already failed to be
      // promoted.
      if (overlay_ptr == nullptr) continue;
      auto iter = base_format_->overlay_extractors_.find(name);
      // If it isn't in the parent, add it.
      if (iter == base_format_->overlay_extractors_.end()) {
        base_format_->overlay_extractors_.insert(
            std::make_pair(name, overlay_ptr));
      } else if (iter->second == nullptr) {
        // Previous attempt fail, don't promote.
        continue;
      } else if (*overlay_ptr != *(iter->second)) {
        // If the base format extractor refers to a different overlay type,
        // fail the promotion.
        base_format_->overlay_extractors_[name] = nullptr;
      }
    }
  }
}

// This is the counterpart to the previous method and cleans up extractors that
// were attempted to be promoted, but couldn't be due to conflicts with others,
// e.g., two fields were named the same in different formats but referred to
// different bits.
void Format::PropagateExtractorsDown() {
  // Remove the extractor entries with null ptrs and any extractors that
  // have been promoted.
  auto e_iter = extractors_.begin();
  while (e_iter != extractors_.end()) {
    auto cur = e_iter++;
    // Failed promotion from derived format extractors.
    if (cur->second == nullptr) {
      extractors_.erase(cur);
      continue;
    }
    // If the name exists in overlay extractors, erase both.
    if (overlay_extractors_.find(cur->first) != overlay_extractors_.end()) {
      overlay_extractors_.erase(cur->first);
      extractors_.erase(cur);
      continue;
    }
  }
  // Remove the overlay extractor entries with null ptrs.
  auto o_iter = overlay_extractors_.begin();
  while (o_iter != overlay_extractors_.end()) {
    auto cur = o_iter++;
    // Failed promotion from derived format extractors.
    if (cur->second == nullptr) {
      overlay_extractors_.erase(cur);
      continue;
    }
    // If the name exists in overlay extractors, erase both.
    if (extractors_.find(cur->first) != extractors_.end()) {
      extractors_.erase(cur->first);
      overlay_extractors_.erase(cur);
      continue;
    }
  }
  for (auto* fmt : derived_formats_) {
    fmt->PropagateExtractorsDown();
  }
}

// Returns true if the current format, or a base format, contains an
// extractor for field 'name'.
bool Format::HasExtract(const std::string& name) const {
  auto iter = extractors_.find(name);
  if ((iter != extractors_.end()) && (iter->second != nullptr)) return true;

  if (base_format_ != nullptr) return base_format_->HasExtract(name);

  return false;
}

// Returns true if the current format, or a base format, contains an
// extractor for overlay 'name'.
bool Format::HasOverlayExtract(const std::string& name) const {
  auto iter = overlay_extractors_.find(name);
  if ((iter != overlay_extractors_.end()) && (iter->second != nullptr)) {
    return true;
  }

  if (base_format_ != nullptr) return base_format_->HasOverlayExtract(name);

  return false;
}

std::string Format::GeneratePackedStructFieldExtractor(
    const Field* field) const {
  std::string h_output;
  int width = field->width;
  std::string return_type = GetUIntType(width);
  std::string signature = absl::StrCat("inline ", return_type, " Extract",
                                       ToPascalCase(field->name), "(");
  if (declared_width_ < 64) {
    absl::StrAppend(&signature, GetUIntType(declared_width_), " value) {\n");
  } else {
    absl::StrAppend(&signature, "const uint8_t *value) {\n");
  }
  absl::StrAppend(&h_output, signature);
  // Now start the body.
  std::string union_type = absl::StrCat("const ", ToSnakeCase(name()),
                                        "::Union", ToPascalCase(name()));
  absl::StrAppend(&h_output, "  ", union_type,
                  " *packed_union;\n"
                  "  packed_union = reinterpret_cast<",
                  union_type, "*>(",
                  declared_width_ > 64 ? "value);\n" : "&value);\n",
                  "  return packed_union->", ToSnakeCase(name()), ".",
                  field->name, ";\n}\n\n");
  return h_output;
}

// This method generates the C++ code for the field extractors for the current
// format.
std::string Format::GenerateFieldExtractor(const Field* field) const {
  std::string h_output;
  int return_width = GetIntTypeBitWidth(field->width);
  std::string result_type_name =
      field->is_signed ? GetIntType(return_width) : GetUIntType(return_width);
  std::string argument_type_name = GetUIntType(computed_width_);
  std::string signature = absl::StrCat(
      result_type_name, " Extract", ToPascalCase(field->name), "(",
      computed_width_ > 128 ? "const " : "", argument_type_name, " value)");

  absl::StrAppend(&h_output, "inline ", signature, " {\n");

  // Generate extraction function. For fields it's a simple shift and mask if
  // the source format width <= 64 bits. Slightly more involved with format
  // <= 128 bits. For larger formats use the templated extract helper function.
  std::string expr;
  if (declared_width_ <= 64) {
    uint64_t mask = (1ULL << field->width) - 1;
    if (field->low == 0) {
      expr = absl::StrCat("value & 0x", absl::Hex(mask));
    } else {
      expr = absl::StrCat(" (value >> ", field->low, ") & 0x", absl::Hex(mask));
    }
  } else if (declared_width_ <= 128) {
    absl::StrAppend(&h_output,
                    "  absl::uint128 mask = 1;\n"
                    "  mask = (mask << ",
                    field->width, ") - 1;\n");
    if (field->low == 0) {
      expr = absl::StrCat("value & mask");
    } else {
      expr = absl::StrCat(" (value >> ", field->low, ") & mask");
    }
  } else {
    // For format width > 128 bits, use the templated extract helper function.
    int byte_size = (declared_width_ + 7) / 8;
    expr = absl::StrCat("internal::ExtractBits<", result_type_name, ">(value, ",
                        byte_size, ", ", field->high, ", ", field->width, ")");
  }

  // Add sign-extension if the field is signed.
  std::string sign_extension;
  if (field->is_signed) {
    int shift = return_width - field->width;
    sign_extension =
        absl::StrCat("  ", result_type_name, " result = (", expr, ") << ",
                     shift, ";\n  result = result >> ", shift, ";\n");
    expr = "result";
  }
  if (declared_width_ <= 64) {
    absl::StrAppend(&h_output, sign_extension, "  return ", expr, ";\n}\n\n");
  } else if ((declared_width_ <= 128) && (return_width <= 64)) {
    absl::StrAppend(&h_output, sign_extension, "  return absl::Uint128Low64(",
                    expr, ");\n}\n\n");
  } else {
    absl::StrAppend(&h_output, sign_extension, "  return ", expr, ";\n}\n\n");
  }
  // If the parent format size is not a power of two, also create an extractor
  // that takes a uint8_t * parameter.
  if ((declared_width_ <= 128) &&
      (absl::popcount(static_cast<unsigned>(declared_width_)) > 1)) {
    absl::StrAppend(&h_output, "inline ", result_type_name, " Extract",
                    ToPascalCase(field->name), "(const uint8_t *value) {\n");
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  return internal::ExtractBits<",
                    result_type_name, ">(value, ", byte_size, ", ", field->high,
                    ", ", field->width, ");\n}\n\n");
  }
  return h_output;
}

std::string Format::GeneratePackedStructFieldInserter(
    const Field* field) const {
  std::string h_output;
  std::string field_type_name;
  std::string inst_word_type_name;
  if (computed_width_ <= 64) {
    inst_word_type_name = GetUIntType(computed_width_);
  } else {
    inst_word_type_name = "uint8_t *";
  }
  field_type_name = GetUIntType(field->width);
  std::string union_type =
      absl::StrCat(ToSnakeCase(name()), "::Union", ToPascalCase(name()));
  absl::StrAppend(&h_output, "static inline ", inst_word_type_name, " Insert",
                  ToPascalCase(field->name), "(", field_type_name, " value, ",
                  inst_word_type_name,
                  " inst_word) {\n"
                  "  ",
                  union_type,
                  " *packed_union;\n"
                  "  packed_union = reinterpret_cast<",
                  union_type, "*>(",
                  (computed_width_ <= 64 ? "&inst_word" : "inst_word"),
                  ");\n"
                  "  packed_union->",
                  ToSnakeCase(name()), ".", field->name,
                  " = value;\n"
                  "  return inst_word;\n"
                  "}\n\n");
  return h_output;
}

// This method generates the C++ code for field inserters for the current
// format. That is, the generated code will take the value of a field and
// insert it into the right place in the instruction word.
std::string Format::GenerateFieldInserter(const Field* field) const {
  std::string h_output;
  std::string field_type_name;
  std::string inst_word_type_name = GetUIntType(computed_width_);
  if (declared_width_ <= 128) {
    field_type_name = inst_word_type_name;
  } else {
    field_type_name = GetUIntType(field->width);
  }
  absl::StrAppend(&h_output, "static inline ", inst_word_type_name, " Insert",
                  ToPascalCase(field->name), "(", field_type_name, " value, ",
                  inst_word_type_name, " inst_word) {\n");
  if (declared_width_ <= 64) {
    uint64_t mask = ((1ULL << field->width) - 1) << field->low;
    std::string shift;
    if (field->low != 0) {
      shift = absl::StrCat(" << ", field->low);
    }
    absl::StrAppend(&h_output, "  inst_word = (inst_word & ~0x",
                    absl::Hex(mask), "ULL)", " | ((value", shift, ") & 0x",
                    absl::Hex(mask),
                    "ULL);\n"
                    "  return inst_word;\n"
                    "}\n");
  } else if (declared_width_ <= 128) {
    absl::StrAppend(&h_output,
                    "  absl::uint128 mask = 1;\n"
                    "  mask = (mask << ",
                    field->width, ") - 1;\n");
    if (field->low != 0) {
      absl::StrAppend(&h_output, "  mask = mask << ", field->low, ";\n");
    }
    absl::StrAppend(&h_output,
                    "  inst_word = (inst_word & ~mask) | (value & mask);\n"
                    "  return inst_word;\n"
                    "}\n");
  } else if (field->width <= 128) {
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ", byte_size,
                    ", ", field->high, ", ", field->width,
                    ", value);\n"
                    "  return inst_word;\n"
                    "}\n");
  } else {
    absl::StrAppend(&h_output,
                    "  LOG(FATAL) << \" Support for fields > 128 bits not "
                    "implemented - "
                    "yet.\";\n"
                    "  return 0;\n}\n");
  }
  return h_output;
}

// This method generates the C++ code for overlay inserters for the current
// format. That is, the generated code will take the value of an overlay and
// insert its components into the right places in the instruction word.
std::string Format::GenerateOverlayInserter(Overlay* overlay) const {
  std::string h_output;
  std::string result_type_name = GetUIntType(computed_width_);
  std::string overlay_type_name;
  if (computed_width_ <= 128) {
    overlay_type_name = result_type_name;
  } else {
    overlay_type_name = GetUIntType(overlay->declared_width());
  }
  absl::StrAppend(&h_output, "static inline ", result_type_name, " Insert",
                  ToPascalCase(overlay->name()), "(", overlay_type_name,
                  " value, ", result_type_name, " inst_word) {\n");
  // Mark error if either the overlay or the format is > 64 bits.
  if (overlay->declared_width() > 128) {
    absl::StrAppend(&h_output,
                    "  LOG(FATAL) << \" Support for overlays > 128 bits "
                    "not implemented - "
                    "yet.\";\n"
                    "  return 0;\n}\n");
    return h_output;
  }
  bool use_mask_variable = false;
  int remaining = overlay->declared_width();
  int byte_size = (declared_width_ + 7) / 8;
  if (declared_width_ <= 128) {
    absl::StrAppend(&h_output, "  ", result_type_name, " tmp;\n");
    // Track the leftmost bit in the overlay.
    if (declared_width_ > 64) {
      absl::StrAppend(&h_output, "  absl::uint128 mask;\n");
      use_mask_variable = true;
    }
  } else {
    absl::StrAppend(&h_output, "  ", overlay_type_name, " tmp;\n");
    if (overlay->declared_width() > 64) {
      absl::StrAppend(&h_output, "  absl::uint128 mask;\n");
      use_mask_variable = true;
    }
  }
  for (auto& bits_or_field : overlay->component_vec()) {
    int width = bits_or_field->width();
    // Ignore the bit fields in the overlay.
    if (bits_or_field->high() < 0) {
      remaining -= width;
      continue;
    }
    std::string shift;
    if (remaining - width > 0) {
      shift = absl::StrCat(" >> ", remaining - width);
    }
    if (use_mask_variable) {
      absl::StrAppend(&h_output,
                      "  mask = 1;\n"
                      "  mask = (mask << ",
                      width, ") - 1;\n");
      absl::StrAppend(&h_output, "  tmp = (value ", shift, ") & mask;\n");
    } else {
      uint64_t mask = ((1ULL << width) - 1);
      // Extract the bits from the overlay value for the current component.
      absl::StrAppend(&h_output, "  tmp = (value ", shift, ") & 0x",
                      absl::Hex(mask), "ULL;\n");
    }
    shift.clear();
    if (bits_or_field->low() != 0) {
      shift = absl::StrCat(" << ", bits_or_field->low());
    }
    if (declared_width_ <= 128) {
      absl::StrAppend(&h_output, "  inst_word |= (tmp ", shift, ");\n");
    } else {
      absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ",
                      byte_size, ", ", bits_or_field->high(), ", ", width,
                      ",  tmp);\n");
    }

    remaining -= width;
  }
  absl::StrAppend(&h_output, "  return inst_word;\n}\n");
  return h_output;
}

std::string Format::GeneratePackedStructFormatInserter(
    std::string_view format_alias, const Format* format, int high,
    int size) const {
  std::string h_output;
  std::string inst_word_type_name;
  if (computed_width_ <= 64) {
    inst_word_type_name = GetUIntType(computed_width_);
  } else {
    inst_word_type_name = "uint8_t *";
  }
  std::string format_type_name = GetUIntType(format->declared_width());
  std::string union_type =
      absl::StrCat(ToSnakeCase(name()), "::Union", ToPascalCase(name()));
  absl::StrAppend(&h_output, "static inline ", inst_word_type_name, " Insert",
                  ToPascalCase(format_alias), "(", format_type_name, " value, ",
                  inst_word_type_name,
                  " inst_word) {\n"
                  "  ",
                  union_type,
                  " *packed_union;\n"
                  "  packed_union = reinterpret_cast<",
                  union_type, "*>(",
                  (computed_width_ <= 64 ? "&inst_word" : "inst_word"),
                  ");\n"
                  "  packed_union->",
                  ToSnakeCase(name()), ".", format_alias,
                  " = value;\n"
                  "  return inst_word;\n"
                  "}\n\n");
  return h_output;
}

// This method generates the C++ code for format inserters for the current
// format. That is, the generated code will take the value of a format and
// insert it into the right place in the instruction word.
std::string Format::GenerateFormatInserter(std::string_view format_alias,
                                           const Format* format, int high,
                                           int size) const {
  if (size > 1) {
    return GenerateReplicatedFormatInserter(format_alias, format, high, size);
  }
  return GenerateSingleFormatInserter(format_alias, format, high);
}

std::string Format::GenerateReplicatedFormatInserter(
    std::string_view format_alias, const Format* format, int high,
    int size) const {
  std::string h_output;
  std::string target_type_name = GetUIntType(declared_width_);
  std::string format_type_name;

  if (declared_width_ <= 128) {
    format_type_name = target_type_name;
  } else {
    format_type_name = GetUIntType(format->declared_width());
  }
  absl::StrAppend(&h_output, "static inline ", target_type_name, " Insert",
                  ToPascalCase(format_alias), "(", "int index, ",
                  format_type_name, " value, ", target_type_name,
                  " inst_word) {\n");
  if (format->declared_width() > 128) {
    absl::StrAppend(&h_output,
                    "  LOG(FATAL) << \" Support for formats > 128 bits not "
                    "implemented - "
                    "yet.\";\n"
                    "  return 0;\n}\n");
    return h_output;
  }
  int width = format->declared_width();
  int low = high - width + 1;
  if (declared_width_ <= 64) {
    uint64_t mask = (1ULL << width) - 1;
    absl::StrAppend(&h_output, "  int low = ", low, " - (index * ", width,
                    ");\n"
                    "  return (inst_word & (~0x",
                    absl::Hex(mask), "ULL << low))", " | ((value << low) & (0x",
                    absl::Hex(mask), "ULL << low));\n}\n");
  } else if (declared_width_ <= 128) {
    absl::StrAppend(
        &h_output, "  int low = ", low, " - (index * ", width,
        ");\n"
        "  absl::uint128 mask = 1;\n"
        "  mask = (mask << ",
        width,
        ") - 1;\n"
        "  mask <<= low;\n"
        "  return (inst_word & ~mask) | (value << low) & mask;\n}\n");
  } else {
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ", byte_size,
                    ", ", high, " - (index * ", width, "), ", width,
                    ", value);\n"
                    "  return inst_word;\n}\n");
  }
  return h_output;
}

std::string Format::GenerateSingleFormatInserter(std::string_view format_alias,
                                                 const Format* format,
                                                 int high) const {
  std::string h_output;
  std::string target_type_name = GetUIntType(declared_width_);
  std::string format_type_name;
  if (declared_width_ <= 128) {
    format_type_name = target_type_name;
  } else {
    format_type_name = GetUIntType(format->declared_width());
  }

  absl::StrAppend(&h_output, "static inline ", target_type_name, " Insert",
                  ToPascalCase(format_alias), "(", format_type_name, " value, ",
                  target_type_name, " inst_word) {\n");
  if (format->declared_width() > 128) {
    absl::StrAppend(&h_output,
                    "  LOG(FATAL) << \" Support for formats > 128 bits not "
                    "implemented - "
                    "yet.\";\n"
                    "  return 0;\n}\n");
    return h_output;
  }
  int width = format->declared_width();
  int low = high - width + 1;
  std::string shift;
  if (low != 0) {
    shift = absl::StrCat(" << ", low);
  }
  if (declared_width_ <= 64) {
    uint64_t mask = ((1ULL << width) - 1) << low;
    absl::StrAppend(&h_output, "  return (inst_word & (~0x", absl::Hex(mask),
                    "ULL))", " | ((value ", shift, ") & 0x", absl::Hex(mask),
                    "ULL);\n}\n");
  } else if (declared_width_ <= 128) {
    absl::StrAppend(&h_output,
                    "  absl::uint128 mask = 1;\n"
                    "  mask = (mask << ",
                    width, ") - 1;\n");
    if (low > 0) {
      absl::StrAppend(&h_output, "  mask = mask << ", low, ";\n");
    }
    absl::StrAppend(&h_output, "  return (inst_word & ~mask) | (value ", shift,
                    ") & mask;\n}\n");
  } else {
    int byte_size = (declared_width_ + 7) / 8;
    absl::StrAppend(&h_output, "  internal::InsertBits(inst_word, ", byte_size,
                    ", ", high, ", ", width,
                    ", value);\n"
                    "  return inst_word;\n}\n");
  }
  return h_output;
}

std::string Format::GeneratePackedStructFormatExtractor(
    absl::string_view format_alias, const Format* format, int high,
    int size) const {
  std::string h_output;
  int width = format->declared_width();
  std::string return_type = GetUIntType(width);
  std::string signature = absl::StrCat("inline ", return_type, " Extract",
                                       ToPascalCase(format_alias), "(");
  if (declared_width_ < 64) {
    absl::StrAppend(&signature, GetUIntType(declared_width_), " value) {\n");
  } else {
    absl::StrAppend(&signature, "const uint8_t *value) {\n");
  }
  absl::StrAppend(&h_output, signature);
  // Now start the body.
  std::string union_type = absl::StrCat("const ", ToSnakeCase(name()),
                                        "::Union", ToPascalCase(name()));
  absl::StrAppend(&h_output, "  ", union_type,
                  " *packed_union;\n"
                  "  packed_union = reinterpret_cast<",
                  union_type, " *>(",
                  declared_width_ > 64 ? "value);\n" : "&value);\n",
                  "  return packed_union->", ToSnakeCase(name()), ".",
                  format_alias, ";\n}\n\n");
  return h_output;
}

// This method generates the format extractors for the current format (for
// when a format contains other formats).
std::string Format::GenerateFormatExtractor(absl::string_view format_alias,
                                            const Format* format, int high,
                                            int size) const {
  std::string h_output;  // For each format generate an extractor.
  int width = format->declared_width();
  // An extraction can only be for 128 bits or less.
  if (width > 128) {
    encoding_info_->error_listener()->semanticError(
        nullptr,
        absl::StrCat("Cannot generate a format extractor for format '",
                     format->name(), "': format is wider than 128 bits"));
    return "";
  }
  std::string return_type = GetUIntType(width);
  std::string signature = absl::StrCat("inline ", return_type, " Extract",
                                       ToPascalCase(format_alias), "(");
  if (declared_width_ <= 128) {
    // If the source format is <= 128 bits, then use an int type.
    std::string arg_type = GetUIntType(declared_width_);
    absl::StrAppend(&signature, arg_type, " value");
  } else {
    // Otherwise use a pointer to uint8_t type.
    absl::StrAppend(&signature, "const uint8_t *value");
  }
  // If the format has multiple instances add an index parameter.
  if (size > 1) {
    absl::StrAppend(&signature, ", int index");
  }
  absl::StrAppend(&signature, ")");
  // Now start the body.
  absl::StrAppend(&h_output, signature, " {\n");
  std::string expr;
  if (declared_width_ <= 128) {
    // If the source format can be stored in a uint128 or smaller.
    int low = high - width + 1;
    std::string shift;
    if (size > 1) {
      shift = absl::StrCat("(", low, " + (index - 1) * ", width, ")");
    } else {
      shift = absl::StrCat(low);
    }
    if (declared_width_ <= 64) {
      uint64_t mask = (1ULL << width) - 1;
      expr =
          absl::StrCat("(value >> ", shift, ") & 0x", absl::Hex(mask), ";\n");
      absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
    } else {
      absl::StrAppend(&h_output,
                      "  absl::uint128 mask = 1;\n"
                      "  mask = (mask << ",
                      width, ") - 1;\n");
      expr = absl::StrCat("(value >> ", shift, ") & mask");
      if (width <= 64) {
        absl::StrAppend(&h_output, "  return absl::Uint128Low64(", expr,
                        ");\n}\n\n");
      } else {
        absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
      }
    }
  } else {
    // If the source format is stored in uint8_t[].
    int byte_size = (declared_width_ + 7) / 8;
    expr = absl::StrCat("internal::ExtractBits<", return_type, ">(value, ",
                        byte_size, ", ", high);
    if (size > 1) {
      absl::StrAppend(&expr, " - (index * ", width, ")");
    }
    absl::StrAppend(&expr, ", ", width, ")");
    absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
  }
  // If the parent format size is not a power of two, also create an
  // extractor that takes a uint8_t * parameter.
  if ((declared_width_ <= 128) &&
      (absl::popcount(static_cast<unsigned>(declared_width_)) > 1)) {
    absl::StrAppend(&h_output, "inline ", return_type, " Extract",
                    ToPascalCase(format_alias), "(const uint8_t *value) {\n");
    int byte_size = (declared_width_ + 7) / 8;
    expr = absl::StrCat("internal::ExtractBits<", return_type, ">(value, ",
                        byte_size, ", ", high);
    if (size > 1) {
      absl::StrAppend(&expr, " - (index * ", width, ")");
    }
    absl::StrAppend(&expr, ", ", width, ")");
    absl::StrAppend(&h_output, "  return ", expr, ";\n}\n\n");
  }
  return h_output;
}

std::string Format::GeneratePackedStructOverlayExtractor(
    Overlay* overlay) const {
  std::string h_output;
  std::string arg_type;
  if (declared_width_ > 128) {
    arg_type = "const uint8_t *";
  } else {
    arg_type = GetUIntType(declared_width_);
  }
  std::string return_type = overlay->is_signed()
                                ? GetIntType(overlay->declared_width())
                                : GetUIntType(overlay->declared_width());
  std::string signature =
      absl::StrCat("inline ", return_type, " Extract",
                   ToPascalCase(overlay->name()), "(", arg_type, " value)");
  absl::StrAppend(&h_output, signature, " {\n  ", return_type, " result;\n",
                  overlay->WritePackedStructValueExtractor("value", "result"));
  if (overlay->is_signed()) {
    int shift = GetIntTypeBitWidth(overlay->declared_width()) -
                overlay->declared_width();
    absl::StrAppend(&h_output, "  result = result << ", shift,
                    ";\n"
                    "  result = result >> ",
                    shift, ";\n");
  }
  absl::StrAppend(&h_output,
                  "  return result;\n"
                  "}\n\n");
  return h_output;
}

// Generates the C++ code for the overlay extractors in the current format.
std::string Format::GenerateOverlayExtractor(Overlay* overlay) const {
  std::string h_output;

  std::string return_type = overlay->is_signed()
                                ? GetIntType(overlay->declared_width())
                                : GetUIntType(overlay->declared_width());

  std::string arg_type = GetUIntType(declared_width_);
  std::string signature =
      absl::StrCat("inline ", return_type, " Extract",
                   ToPascalCase(overlay->name()), "(", arg_type, " value)");

  // Generate definition.
  absl::StrAppend(&h_output, signature,
                  " {\n"
                  "  ",
                  return_type, " result;\n");
  if (declared_width_ <= 64) {
    absl::StrAppend(&h_output,
                    overlay->WriteSimpleValueExtractor("value", "result"));
  } else {
    absl::StrAppend(&h_output, overlay->WriteComplexValueExtractor(
                                   "value", "result", return_type));
  }
  if (overlay->is_signed()) {
    int shift = GetIntTypeBitWidth(overlay->declared_width()) -
                overlay->declared_width();
    absl::StrAppend(&h_output, "  result = result << ", shift,
                    ";\n"
                    "  result = result >> ",
                    shift, ";\n");
  }
  if ((declared_width_ > 64) && (overlay->declared_width() <= 64)) {
    absl::StrAppend(&h_output,
                    "  return UInt128Low64(result();\n"
                    "}\n\n");
  } else {
    absl::StrAppend(&h_output,
                    "  return result;\n"
                    "}\n\n");
  }
  return h_output;
}

// Top level function called to generate all the inserters for this format.
std::string Format::GenerateInserters() const {
  std::string class_output;
  std::string h_output;
  if (extractors_.empty() && overlay_extractors_.empty()) {
    return h_output;
  }
  absl::StrAppend(&h_output, "struct ", ToPascalCase(name()), " {\n\n");
  // First fields and formats.
  std::string inserter;
  for (auto& [unused, field_or_format_ptr] : extractors_) {
    if (field_or_format_ptr->is_field()) {
      if (layout() == Layout::kPackedStruct) {
        inserter =
            GeneratePackedStructFieldInserter(field_or_format_ptr->field());
      } else {
        inserter = GenerateFieldInserter(field_or_format_ptr->field());
      }
      absl::StrAppend(&h_output, inserter);
    } else {
      if (layout() == Layout::kPackedStruct) {
        inserter = GeneratePackedStructFormatInserter(
            field_or_format_ptr->format_alias(), field_or_format_ptr->format(),
            field_or_format_ptr->high(), field_or_format_ptr->size());
      } else {
        inserter = GenerateFormatInserter(
            field_or_format_ptr->format_alias(), field_or_format_ptr->format(),
            field_or_format_ptr->high(), field_or_format_ptr->size());
      }
      absl::StrAppend(&h_output, inserter);
    }
  }
  // Next the overlays.
  for (auto& [unused, overlay_ptr] : overlay_extractors_) {
    auto inserter = GenerateOverlayInserter(overlay_ptr);
    absl::StrAppend(&h_output, inserter);
  }
  absl::StrAppend(&h_output, "};  // struct ", ToPascalCase(name()), "\n\n");
  return h_output;
}

std::string Format::GeneratePackedStructTypes() const {
  std::string h_output;
  // First the struct.
  absl::StrAppend(&h_output, "struct Packed", ToPascalCase(name()), " {\n");
  for (auto it = field_vec_.rbegin(); it != field_vec_.rend(); ++it) {
    auto* component = *it;
    if (component->is_field()) {
      int width = component->field()->width;
      std::string field_type = component->field()->is_signed
                                   ? GetIntType(width)
                                   : GetUIntType(width);
      absl::StrAppend(&h_output, "  ", field_type, " ",
                      component->field()->name, " : ",
                      component->field()->width, ";\n");
    } else {
      absl::StrAppend(&h_output, "  ",
                      GetUIntType(component->format()->declared_width()), " ",
                      component->format_alias(), " : ",
                      component->format()->declared_width(), ";\n");
    }
  }
  absl::StrAppend(&h_output, "} ABSL_ATTRIBUTE_PACKED;\n\n");
  // Next the union.
  int num_bytes = (declared_width_ + 7) / 8;
  absl::StrAppend(&h_output, "union Union", ToPascalCase(name()),
                  " {\n"
                  "  Packed",
                  ToPascalCase(name()), " ", ToSnakeCase(name()),
                  ";\n"
                  "  uint8_t bytes[",
                  num_bytes, "];\n");
  // If it is 64 bits or less, add an unsigned integer value type.
  if (declared_width_ <= 64) {
    absl::StrAppend(&h_output, "  ", GetUIntType(declared_width_), " value;\n");
  }
  absl::StrAppend(&h_output, "};\n\n");
  return h_output;
}

// Top level function called to generate all the extractors for this format.
Extractors Format::GenerateExtractors() const {
  Extractors extractors;
  if (extractors_.empty() && overlay_extractors_.empty()) {
    return extractors;
  }

  extractors.class_output =
      absl::StrCat("class ", ToPascalCase(name()), " {\n public:\n", "  ",
                   ToPascalCase(name()), "() = default;\n\n");

  // Use a separate namespace for each format.
  extractors.h_output =
      absl::StrCat("namespace ", ToSnakeCase(name()), " {\n\n");
  extractors.types_output =
      absl::StrCat("namespace ", ToSnakeCase(name()), " {\n\n");

  std::string get_size = absl::StrCat("constexpr int k", ToPascalCase(name()),
                                      "Size = ", declared_width(), ";\n\n");
  absl::StrAppend(&extractors.h_output, get_size);
  absl::StrAppend(&extractors.class_output, "static ", get_size);

  // If this format has a packed struct layout, generate the types required.
  if (layout() == Layout::kPackedStruct) {
    absl::StrAppend(&extractors.types_output, GeneratePackedStructTypes());
  }

  // First fields and formats.
  for (auto& [unused, field_or_format_ptr] : extractors_) {
    if (field_or_format_ptr->is_field()) {
      std::string extractor;
      if (layout() == Layout::kPackedStruct) {
        extractor =
            GeneratePackedStructFieldExtractor(field_or_format_ptr->field());
      } else {
        extractor = GenerateFieldExtractor(field_or_format_ptr->field());
      }
      absl::StrAppend(&extractors.h_output, extractor);
      absl::StrAppend(&extractors.class_output, "static ", extractor);
    } else {
      std::string extractor;
      if (layout() == Layout::kPackedStruct) {
        extractor = GeneratePackedStructFormatExtractor(
            field_or_format_ptr->format_alias(), field_or_format_ptr->format(),
            field_or_format_ptr->high(), field_or_format_ptr->size());
      } else {
        extractor = GenerateFormatExtractor(
            field_or_format_ptr->format_alias(), field_or_format_ptr->format(),
            field_or_format_ptr->high(), field_or_format_ptr->size());
      }
      absl::StrAppend(&extractors.h_output, extractor);
      absl::StrAppend(&extractors.class_output, "static ", extractor);
    }
  }

  // Then the overlays.
  for (auto& [unused, overlay_ptr] : overlay_extractors_) {
    std::string extractor;
    if (layout() == Layout::kPackedStruct) {
      extractor = GeneratePackedStructOverlayExtractor(overlay_ptr);
    } else {
      extractor = GenerateOverlayExtractor(overlay_ptr);
    }
    absl::StrAppend(&extractors.h_output, extractor);
    absl::StrAppend(&extractors.class_output, "static ", extractor);
  }

  absl::StrAppend(&extractors.h_output, "}  // namespace ", ToSnakeCase(name()),
                  "\n\n");
  absl::StrAppend(&extractors.types_output, "}  // namespace ",
                  ToSnakeCase(name()), "\n\n");
  absl::StrAppend(&extractors.class_output, "};\n\n");
  return extractors;
}

bool Format::IsDerivedFrom(const Format* format) {
  if (format == this) return true;
  if (base_format_ == nullptr) return false;
  if (base_format_ == format) return true;
  return base_format_->IsDerivedFrom(format);
}

}  // namespace bin_format
}  // namespace decoder
}  // namespace sim
}  // namespace mpact
