#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 <vector>

#include "absl/container/btree_map.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "antlr4-runtime/antlr4-runtime.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 fmt_name, int size, antlr4::Token *ctx)
      : is_field_(false), format_name_(fmt_name), size_(size), ctx_(ctx) {}

  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_; }
  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_;
  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 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 the field and overlay extractors in the format.
  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(Field *field);
  std::string GenerateFormatExtractor(Format *format, int high, int size);
  std::string GenerateOverlayExtractor(Overlay *overlay);
  // Return string representation of the int type that contains bitwidth bits.
  std::string GetIntType(int bitwidth);
  int GetIntTypeBitWidth(int bitwidth);

  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_
