// 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.

#ifndef MPACT_SIM_DECODER_PROTO_INSTRUCTION_ENCODING_H_
#define MPACT_SIM_DECODER_PROTO_INSTRUCTION_ENCODING_H_

#include <cstdint>
#include <string>
#include <vector>

#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/proto_constraint_expression.h"
#include "mpact/sim/decoder/proto_format_contexts.h"
#include "src/google/protobuf/descriptor.h"

namespace proto2 {
class FieldDescriptor;
}

namespace mpact {
namespace sim {
namespace decoder {
namespace proto_fmt {

enum class ConstraintType : int { kEq = 0, kNe, kLt, kLe, kGt, kGe, kHas };

inline std::string GetOpText(ConstraintType op) {
  switch (op) {
    case ConstraintType::kEq:
      return "==";
    case ConstraintType::kNe:
      return "!=";
    case ConstraintType::kLt:
      return "<";
    case ConstraintType::kLe:
      return "<=";
    case ConstraintType::kGt:
      return ">";
    case ConstraintType::kGe:
      return ">=";
    case ConstraintType::kHas:
      return "";
  }
}

// Struct to store information about an encoding constraint for an instruction.
struct ProtoConstraint {
  // Parsing context.
  FieldConstraintCtx *ctx;
  // The proto field descriptor for which the constraint applies.
  const google::protobuf::FieldDescriptor *field_descriptor;
  // The constraint type.
  ConstraintType op;
  // If non-null, the expression that applies to the constraint.
  const ProtoConstraintExpression *expr;
  // If the value is compatible with int64_t, the value of the expression. This
  // is filled in later when the expression is evaluated for decoding purposes.
  int64_t value;
  // If non-null, points to a constraint that has to be true before one can
  // evaluate this constraint.
  ProtoConstraint *depends_on;
  // Constructors.
  ProtoConstraint(FieldConstraintCtx *ctx,
                  const google::protobuf::FieldDescriptor *field_descriptor,
                  ConstraintType op, const ProtoConstraintExpression *expr,
                  int64_t value, ProtoConstraint *depends_on)
      : ctx(ctx),
        field_descriptor(field_descriptor),
        op(op),
        expr(expr),
        value(value),
        depends_on(depends_on) {}
  ProtoConstraint(FieldConstraintCtx *ctx,
                  const google::protobuf::FieldDescriptor *field_descriptor,
                  ConstraintType op)
      : ProtoConstraint(ctx, field_descriptor, op, nullptr, 0, nullptr) {}
  // Copy constructor.
  ProtoConstraint(const ProtoConstraint &rhs) {
    this->ctx = rhs.ctx;
    this->field_descriptor = rhs.field_descriptor;
    this->op = rhs.op;
    this->expr = rhs.expr != nullptr ? rhs.expr->Clone() : nullptr;
    this->value = rhs.value;
    this->depends_on = rhs.depends_on;
  }
};

// Struct to store information about a setter for an instruction encoding.
struct ProtoSetter {
  // Proto setter context.
  SetterDefCtx *ctx;
  // The name of the object that is set.
  std::string name;
  // The field that will provide the type and value of the object.
  const google::protobuf::FieldDescriptor *field_descriptor;
  // Default value of the object if the field descriptor is not valid.
  IfNotCtx *if_not;
  // If non-null, points to constraint that has to be true in order to access
  // the value of the field described by field_descriptor.
  ProtoConstraint *depends_on;
};

class ProtoInstructionGroup;

// This class captures all the encoding constraints and the setters for one
// instruction in an instruction group.
class ProtoInstructionEncoding {
 public:
  ProtoInstructionEncoding(std::string name, ProtoInstructionGroup *parent);
  ProtoInstructionEncoding(const ProtoInstructionEncoding &rhs);
  ProtoInstructionEncoding() = delete;
  ProtoInstructionEncoding &operator=(
      const ProtoInstructionEncoding &encoding) = delete;
  ~ProtoInstructionEncoding();

  // Adds a value setter that is executed when the instruction is successfully
  // decoded. This is used to make values, such as register numbers, immediate
  // values, etc., that could be stored in a nested one_of submessage, available
  // at known names.
  absl::Status AddSetter(
      SetterDefCtx *ctx, const std::string &name,
      const google::protobuf::FieldDescriptor *field_descriptor,
      const std::vector<const google::protobuf::FieldDescriptor *>
          &one_of_fields,
      IfNotCtx *if_not);
  // Adds an encoding constraint for the current instruction. Encoding
  // constraints provide constraints on values of proto message fields that
  // have to be satisfied in order for the instruction to match.
  absl::Status AddConstraint(
      FieldConstraintCtx *ctx, ConstraintType op,
      const google::protobuf::FieldDescriptor *field_descriptor,
      const std::vector<const google::protobuf::FieldDescriptor *>
          &one_of_fields,
      const ProtoConstraintExpression *expr);

  // Call when the setters and constraints have been added in order to generate
  // the setter code into the setter_code_ variable.
  void GenerateSetterCode();
  // Get setter code, substituting 'message_name' for '$' in the text.
  std::string GetSetterCode(absl::string_view message_name, int indent) const;
  // Getters.
  const std::string &name() const { return name_; }
  ProtoInstructionGroup *instruction_group() const {
    return instruction_group_;
  }
  std::vector<ProtoConstraint *> &equal_constraints() {
    return equal_constraints_;
  }
  std::vector<ProtoConstraint *> &other_constraints() {
    return other_constraints_;
  }
  absl::flat_hash_map<std::string, ProtoConstraint *> &has_constraints() {
    return has_constraints_;
  }

  std::string setter_code() const { return setter_code_; }

 private:
  // Returns a pointer to the constraint for field_descriptor if it exists. If
  // it does not exist, it creates it and adds it to the has_constraints and
  // returns a pointer to the new constraint. If depends_on is not nullptr,
  // then it is required that the depends_on constraint exists in the
  // has_constraints_ map. This is checked by searching for the full_name of
  // the field_descriptor in the depends_on constraint.
  ProtoConstraint *AddHasConstraint(
      const google::protobuf::FieldDescriptor *field_descriptor,
      ProtoConstraint *depends_on);

  // Instruction name.
  std::string name_;
  // Parent instruction group.
  ProtoInstructionGroup *instruction_group_ = nullptr;
  // Setter code for this encoding.
  std::string setter_code_;
  // Map from setter names to the setter structs.
  absl::btree_map<std::string, ProtoSetter *> setter_map_;
  // Map from one_of descriptor to field.
  absl::flat_hash_map<const google::protobuf::OneofDescriptor *,
                      const google::protobuf::FieldDescriptor *>
      oneof_field_map_;
  // "equal-to" field constraints.
  std::vector<ProtoConstraint *> equal_constraints_;
  // All other constraints.
  std::vector<ProtoConstraint *> other_constraints_;
  // Has Constraints, these are required one_of members that other constraints
  // may depend on.
  absl::flat_hash_map<std::string, ProtoConstraint *> has_constraints_;
};

}  // namespace proto_fmt
}  // namespace decoder
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_DECODER_PROTO_INSTRUCTION_ENCODING_H_
