#ifndef MPACT_SIM_DECODER_FORMAT_H_
#define MPACT_SIM_DECODER_FORMAT_H_

// 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 <map>
#include <string>
#include <tuple>
#include <vector>

#include "absl/container/btree_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "antlr4-runtime/Token.h"

// This file declares the classes necessary to manage instruction formats,
// defined as a sequence of fields (or sub-formats) as well as a set of
// overlays. The format provides a way of defining an interface for accessing
// the different parts of an instruction encoding.

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

class BinEncodingInfo;
class Overlay;
class Format;

// Helper struct to store the information about an individual field.
struct Field {
  std::string name;
  bool is_signed;
  int high;
  int low;
  int width;
  Format *format = nullptr;
  Field(std::string name_, bool is_signed_, int width_, Format *format_)
      : name(name_),
        is_signed(is_signed_),
        high(-1),
        low(-1),
        width(width_),
        format(format_) {}
};

class Format;

// Captures a reference to a format by name and how many instances.
struct FormatReference {
  std::string name;
  int size;
  explicit FormatReference(std::string name_) : FormatReference(name_, 1) {}
  FormatReference(std::string name_, int size_) : name(name_), size(size_) {}
};

// Wrapper class to store information about each component of the format.

class FieldOrFormat {
 public:
  explicit FieldOrFormat(Field *field) : is_field_(true), field_(field) {}
  FieldOrFormat(std::string format_alias, std::string fmt_name, int size,
                antlr4::Token *ctx)
      : is_field_(false),
        format_name_(fmt_name),
        format_alias_(format_alias),
        size_(size),
        ctx_(ctx) {}
  ~FieldOrFormat();

  bool is_field() const { return is_field_; }
  Field *field() const { return field_; }
  int high() const { return high_; }
  void set_high(int value) { high_ = value; }
  const std::string &format_name() const { return format_name_; }
  antlr4::Token *ctx() const { return ctx_; }
  Format *format() const { return format_; }
  absl::string_view format_alias() const { return format_alias_; }
  int size() const { return size_; }
  void set_format(Format *fmt) { format_ = fmt; }

  bool operator==(const FieldOrFormat &rhs) const;
  bool operator!=(const FieldOrFormat &rhs) const;

 private:
  bool is_field_;
  Field *field_ = nullptr;
  std::string format_name_;
  std::string format_alias_;
  int high_ = 0;
  int size_ = 0;
  antlr4::Token *ctx_ = nullptr;
  Format *format_ = nullptr;
};

class Format {
 public:
  Format() = delete;
  Format(std::string name, int width, BinEncodingInfo *encoding_info);
  Format(std::string name, int width, std::string base_format_name,
         BinEncodingInfo *encoding_info);
  ~Format();

  // Adds a field (signed or unsigned) of the given width to the format.
  absl::Status AddField(std::string name, bool is_signed, int width);
  // Adds a format reference to the current format. It will be resolved to
  // another format later, or generate an error at that time.
  void AddFormatReferenceField(std::string format_alias,
                               std::string format_name, int size,
                               antlr4::Token *ctx);
  // Adds an overlay to the format. An overlay is an alias to a set of bits
  // in the instruction format.
  absl::StatusOr<Overlay *> AddFieldOverlay(std::string name, bool is_signed,
                                            int width);

  // Returns the named field if it exists in the format. Otherwise it returns
  // nullptr.
  Field *GetField(absl::string_view field_name) const;
  // Returns the named overlay if it exists in the format. Otherwise it returns
  // nullptr.
  Overlay *GetOverlay(absl::string_view overlay_name) const;

  // Performs a consistency check on the format.
  absl::Status ComputeAndCheckFormatWidth();
  // Propagate extractors to the top level in the format inheritance
  // hierarchy.
  void PropagateExtractorsUp();
  void PropagateExtractorsDown();
  // Generates definitions of the field and overlay extractors in the format.
  std::tuple<std::string, std::string> GenerateExtractors();

  // True if the current format is a descendent of format.
  bool IsDerivedFrom(const Format *format);

  // Accessors.
  const std::string &name() const { return name_; }
  // The unsigned integer type name larger or equal to the format width.
  // E.g. uint32_t etc.
  const std::string &uint_type_name() const { return uint_type_name_; }
  int declared_width() const { return declared_width_; }
  int computed_width() const { return computed_width_; }
  Format *base_format() const { return base_format_; }
  // Return pointer to the parent encoding info class.
  BinEncodingInfo *encoding_info() const { return encoding_info_; }

 private:
  bool HasExtract(const std::string &name) const;
  bool HasOverlayExtract(const std::string &name) const;

  std::string GenerateFieldExtractor(const Field *field) const;
  std::string GenerateFormatExtractor(std::string_view format_alias,
                                      const Format *format, int high,
                                      int size) const;
  std::string GenerateOverlayExtractor(Overlay *overlay) const;
  // Return string representation of the int type that contains bitwidth bits.
  std::string GetIntType(int bitwidth) const;
  int GetIntTypeBitWidth(int bitwidth) const;

  std::string name_;
  std::string base_format_name_;
  std::string uint_type_name_;
  std::string int_type_name_;
  int declared_width_;
  int computed_width_ = 0;
  Format *base_format_ = nullptr;
  std::vector<Format *> derived_formats_;
  BinEncodingInfo *encoding_info_;

  absl::btree_map<std::string, Overlay *> overlay_map_;
  absl::btree_map<std::string, Field *> field_map_;
  std::vector<FieldOrFormat *> field_vec_;
  // Using std::map because of sorted traversal and better iterator stability
  // when elements are erased.
  std::map<std::string, FieldOrFormat *> extractors_;
  std::map<std::string, Overlay *> overlay_extractors_;
};

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

#endif  // MPACT_SIM_DECODER_FORMAT_H_
