// 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 <string>
#include <utility>

#include "absl/numeric/bits.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.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_;
  } else {
    delete format_;
  }
  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 name, int size,
                                     antlr4::Token *ctx) {
  field_vec_.push_back(new FieldOrFormat(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 64 bits, will use a byte array (int8_t *).
std::string Format::GetIntType(int bitwidth) {
  if (bitwidth > 64) return "int8_t *";
  return absl::StrCat("int", GetIntTypeBitWidth(bitwidth), "_t");
}

// Return the int type byte width (1, 2, 4, 8) or (-1 if it's bigger), of the
// integer type that would fit this format.
int Format::GetIntTypeBitWidth(int bitwidth) {
  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 > 6) 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(format->name(), field_or_format));
    }
    if (computed_width_ != declared_width_) {
      return absl::InternalError(
          absl::StrCat("Format '", name_, "': computed width ", computed_width_,
                       " differs from declared width ", declared_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 nullptrs 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 nullptrs.
  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;
}

// This method generates the C++ code for the field extractors for the current
// format.
std::string Format::GenerateFieldExtractor(Field *field) {
  std::string h_output;
  int return_width = GetIntTypeBitWidth(field->width);
  std::string result_type_name =
      absl::StrCat(field->is_signed ? "" : "u", GetIntType(return_width));
  std::string argument_type_name =
      absl::StrCat("u", GetIntType(computed_width_));
  std::string signature =
      absl::StrCat(result_type_name, " Extract", ToPascalCase(field->name), "(",
                   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.
  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 {
    // For format width > 64 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.
  if (field->is_signed) {
    int shift = return_width - field->width;
    absl::StrAppend(&h_output, "  ", result_type_name, " result = (", expr,
                    ") << ", shift, ";\n  result = result >> ", shift, ";\n",
                    "  return result;\n}\n\n");
  } else {
    absl::StrAppend(&h_output, "  return ", expr, ";\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(Format *format, int high,
                                            int size) {
  std::string h_output;  // For each format generate am extractor.
  int width = format->declared_width();
  // An extraction can only be for 64 bits or less.
  if (width > 64) {
    encoding_info_->error_listener()->semanticError(
        nullptr,
        absl::StrCat("Cannot generate a format extractor for format '",
                     format->name(), "': format is wider than 64 bits"));
    return "";
  }
  std::string return_type = absl::StrCat("u", GetIntType(width));
  std::string signature = absl::StrCat("inline ", return_type, " Extract",
                                       ToPascalCase(format->name()), "(");
  if (declared_width_ <= 64) {
    // If the source format is <= 64 bits, then use an int type.
    std::string arg_type = absl::StrCat("u", GetIntType(declared_width_));
    absl::StrAppend(&signature, arg_type, " value");
  } else {
    // Otherwise use a pointer to uint8_t type.
    absl::StrAppend(&signature, "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_ <= 64) {
    // If the source format can be stored in a uint64_t or smaller.
    uint64_t mask = (1ULL << width) - 1;
    int low = high - width + 1;
    int shift_amount = GetIntTypeBitWidth(declared_width_) - low;
    std::string shift;
    if (size > 1) {
      shift = absl::StrCat("(", shift_amount, " - (index - 1) * ", width, ")");
    } else {
      shift = absl::StrCat(shift_amount);
    }
    expr = absl::StrCat("(value >> ", shift, ") & 0x", absl::Hex(mask), ";\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");
  return h_output;
}

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

  std::string return_type = absl::StrCat(overlay->is_signed() ? "" : "u",
                                         GetIntType(overlay->declared_width()));
  std::string arg_type = absl::StrCat("u", GetIntType(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"));
  }
  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;
}

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

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

  // First fields and formats.
  for (auto &[unused, field_or_format_ptr] : extractors_) {
    if (field_or_format_ptr->is_field()) {
      absl::StrAppend(&h_output,
                      GenerateFieldExtractor(field_or_format_ptr->field()));
    } else {
      absl::StrAppend(&h_output,
                      GenerateFormatExtractor(field_or_format_ptr->format(),
                                              field_or_format_ptr->high(),
                                              field_or_format_ptr->size()));
    }
  }

  // Then the overlays.
  for (auto &[unused, overlay_ptr] : overlay_extractors_) {
    absl::StrAppend(&h_output, GenerateOverlayExtractor(overlay_ptr));
  }

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

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
