#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) {}
  ~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_; }
  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_
