#ifndef _UHDM_AST_H_
#define _UHDM_AST_H_ 1

#include "frontends/ast/ast.h"
#include <vector>
#undef cover

#include "uhdmastshared.h"
#include <memory>
#include <uhdm/uhdm.h>

namespace systemverilog_plugin
{

class AstNodeBuilder;

class UhdmAst
{
  private:
    // Logging method for exclusive use of `uhdmast_assert` macro.
    void uhdmast_assert_log(const char *expr_str, const char *func, const char *file, int line) const;

    // Walks through one-to-many relationships from given parent
    // node through the VPI interface, visiting child nodes belonging to
    // ChildrenNodeTypes that are present in the given object.
    void visit_one_to_many(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(::Yosys::AST::AstNode *)> &f);

    // Walks through one-to-one relationships from given parent
    // node through the VPI interface, visiting child nodes belonging to
    // ChildrenNodeTypes that are present in the given object.
    void visit_one_to_one(const std::vector<int> child_node_types, vpiHandle parent_handle, const std::function<void(::Yosys::AST::AstNode *)> &f);

    // Visit children of type vpiRange that belong to the given parent node.
    void visit_range(vpiHandle obj_h, const std::function<void(::Yosys::AST::AstNode *)> &f);

    // Visit the default expression assigned to a variable.
    void visit_default_expr(vpiHandle obj_h);

    // Reads location info (start/end line/column numbers, file name) from `obj_h` and sets them on `target_node`.
    void apply_location_from_current_obj(::Yosys::AST::AstNode &target_node) const;
    // Reads object name from `obj_h` and assigns it to `target_node`.
    void apply_name_from_current_obj(::Yosys::AST::AstNode &target_node) const;

    // Creates node of specified `type` with location properties read from `obj_h`.
    AstNodeBuilder make_node(::Yosys::AST::AstNodeType type) const;
    // Creates node of specified `type` with location properties and name read from `obj_h`.
    AstNodeBuilder make_named_node(::Yosys::AST::AstNodeType type) const;
    // Creates AST_IDENTIFIER node with specified `id` and location properties read from `obj_h`.
    AstNodeBuilder make_ident(std::string id) const;
    // Creates signed AST_CONSTANT node with specified `value` and location properties read from `obj_h`.
    AstNodeBuilder make_const(int32_t value, uint8_t width = 32) const;
    // Creates unsigned AST_CONSTANT node with specified `value` and location properties read from `obj_h`.
    AstNodeBuilder make_const(uint32_t value, uint8_t width = 32) const;

    // Create an AstNode of the specified type with metadata extracted from
    // the given vpiHandle.
    // OBSOLETE: use `make_node` or `make_named_node` instead.
    ::Yosys::AST::AstNode *make_ast_node(::Yosys::AST::AstNodeType type, std::vector<::Yosys::AST::AstNode *> children = {});

    // Create an identifier AstNode
    // OBSOLETE: use `make_ident` instead.
    ::Yosys::AST::AstNode *make_identifier(std::string name);

    // Makes the passed node a cell node of the specified type
    void make_cell(vpiHandle obj_h, ::Yosys::AST::AstNode *node, ::Yosys::AST::AstNode *type);

    // Moves a type node to the specified node
    void move_type_to_new_typedef(::Yosys::AST::AstNode *current_node, ::Yosys::AST::AstNode *type_node);

    // Go up the UhdmAst to find a parent node of the specified type
    ::Yosys::AST::AstNode *find_ancestor(const std::unordered_set<::Yosys::AST::AstNodeType> &types);

    // Reports that something went wrong with reading the UHDM file
    void report_error(const char *format, ...) const;

    // Processes the value connected to the specified node
    ::Yosys::AST::AstNode *process_value(vpiHandle obj_h);

    // Transforms break and continue nodes into structures accepted by the AST frontend
    void transform_breaks_continues(::Yosys::AST::AstNode *loop, ::Yosys::AST::AstNode *decl_block);

    // The parent UhdmAst
    UhdmAst *parent;

    // Data shared between all UhdmAst objects
    UhdmAstShared &shared;

    // The current VPI/UHDM handle
    vpiHandle obj_h = 0;

    // The current Yosys AST node
    ::Yosys::AST::AstNode *current_node = nullptr;

    // Indentation used for debug printing
    std::string indent;

    // Mapping of names that should be replaced to new names
    std::unordered_map<std::string, std::string> node_renames;

    // Functions that process specific types of nodes
    void process_design();
    void process_parameter();
    void process_port();
    void process_module();
    void process_struct_typespec();
    void process_union_typespec();
    void process_packed_array_typespec();
    void process_array_typespec();
    void process_typespec_member();
    void process_enum_typespec();
    void process_enum_const();
    void process_custom_var();
    void process_int_var();
    void process_real_var();
    void process_array_var();
    void process_packed_array_var();
    void process_param_assign();
    void process_cont_assign();
    void process_cont_assign_net();
    void process_cont_assign_var_init();
    void process_assignment(const UHDM::BaseClass *object);
    void process_net();
    void process_packed_array_net();
    void process_array_net(const UHDM::BaseClass *object);
    void process_package();
    void process_interface();
    void process_modport();
    void process_io_decl();
    void process_always();
    void process_event_control(const UHDM::BaseClass *object);
    void process_initial();
    void process_begin(bool is_named);
    void process_operation(const UHDM::BaseClass *object);
    void process_stream_op();
    void process_list_op();
    void process_cast_op();
    void process_inside_op();
    void process_assignment_pattern_op();
    void process_tagged_pattern();
    void process_bit_select();
    void process_part_select();
    void process_indexed_part_select();
    void process_var_select();
    void process_if_else();
    void process_for();
    void process_gen_scope_array();
    void process_gen_scope();
    void process_case();
    void process_case_item();
    void process_range(const UHDM::BaseClass *object);
    void process_return();
    void process_function();
    void process_logic_var();
    void process_sys_func_call();
    // use for task calls and function calls
    void process_tf_call(::Yosys::AST::AstNodeType type);
    void process_immediate_assert();
    void process_hier_path();
    void process_logic_typespec();
    void process_int_typespec();
    void process_shortint_typespec();
    void process_longint_typespec();
    void process_time_typespec();
    void process_bit_typespec();
    void process_string_var();
    void process_string_typespec();
    void process_repeat();
    void process_byte_var();
    void process_byte_typespec();
    void process_long_int_var();
    void process_immediate_cover();
    void process_immediate_assume();
    void process_while();
    void process_gate();
    void process_primterm();
    void process_type_parameter();
    void simplify_parameter(::Yosys::AST::AstNode *parameter, ::Yosys::AST::AstNode *module_node = nullptr);
    void process_unsupported_stmt(const UHDM::BaseClass *object, bool is_error = true);

    UhdmAst(UhdmAst *p, UhdmAstShared &s, const std::string &i) : parent(p), shared(s), indent(i)
    {
        if (parent)
            node_renames = parent->node_renames;
    }

  public:
    UhdmAst(UhdmAstShared &s, const std::string &i = "") : UhdmAst(nullptr, s, i) {}

    // Visits single VPI object and creates proper AST node
    ::Yosys::AST::AstNode *process_object(vpiHandle obj_h);

    // Visits all VPI design objects and returns created ASTs
    ::Yosys::AST::AstNode *visit_designs(const std::vector<vpiHandle> &designs);

    static const ::Yosys::IdString &partial();
    static const ::Yosys::IdString &packed_ranges();
    static const ::Yosys::IdString &unpacked_ranges();
    // set this attribute to force conversion of multirange wire to single range. It is useful to force-convert some memories.
    static const ::Yosys::IdString &force_convert();
    static const ::Yosys::IdString &is_imported();
    static const ::Yosys::IdString &is_simplified_wire();
    static const ::Yosys::IdString &low_high_bound();
    static const ::Yosys::IdString &is_elaborated_module();
};

// Utility for building AstNode trees.
//
// The object members that set AstNode properties return rvalue reference to *this (i.e. to the builder object), so they can be chained.
// The children list is set using call operator (`builder_object({child0, child1, ...})`).
// Build finalization is done through cast operator to either `AstNode*` or `std::unique_ptr<AstNode>`.
//
// Usage example:
//
// 1. Define one or more factory functions for creating base AstNode object:
//
//     const auto make_node = [](AST::AstNodeType type) {
//         auto node = std::make_unique<AST::AstNode>(type);
//         // ...initialize the node if needed...
//         return AstNodeBuilder(std::move(node));
//     };
//
// 2. Use the factories to create a tree:
//
//     // AST::AstNode *const variable_node = ...
//     // AST::AstNode *const value_node = ...
//     AST::AstNode *const assign = //
//       (make_node(AST::AST_ASSIGN_EQ))({
//         (make_node(AST::AST_IDENTIFIER).str(variable_node->str)),
//         (make_node(Yosys::AST::AST_ADD))({
//           (make_node(AST::AST_IDENTIFIER).str(value_node->str)),
//           (make_node(AST::AST_CONSTANT).value(4)),
//         }),
//       });
//
// In the real code instead of custom factories illustrated in point 1 above, you probably should use predefined methods from `UhdmAst` class.
// The syntax above puts the factory call and all its method calls (but not the function call operator with the children list) in `()`. This is done
// to make `clang-format` format the code as presented. Otherwise it is heavily wrapped and a lot less readable. `()` are technically not required
// in leafs to make them format as expected, but its nice to use them for consistency.
class AstNodeBuilder
{
    using AstNode = ::Yosys::AST::AstNode;
    using AstNodeType = ::Yosys::AST::AstNodeType;

    std::unique_ptr<AstNode> node;

  public:
    explicit AstNodeBuilder(AstNodeType node_type) : node(new AstNode(node_type)) {}
    explicit AstNodeBuilder(std::unique_ptr<AstNode> node) : node(std::move(node)) {}
    ~AstNodeBuilder() { log_assert(node == nullptr); }

    AstNodeBuilder(AstNodeBuilder &&) = default;

    AstNodeBuilder() = delete;
    AstNodeBuilder(const AstNodeBuilder &) = delete;
    AstNodeBuilder &operator=(const AstNodeBuilder &) = delete;
    AstNodeBuilder &operator=(AstNodeBuilder &&) = delete;

    // Property setters

    // Sets `AstNode::children` vector
    AstNodeBuilder &&operator()(std::vector<AstNode *> children) { return node->children = std::move(children), std::move(*this); }

    // Sets `AstNode::str` value.
    AstNodeBuilder &&str(std::string s) { return node->str = std::move(s), std::move(*this); }

    // Sets `AstNode::integer` value.
    AstNodeBuilder &&integer(uint32_t v) { return node->integer = v, std::move(*this); }

    // Sets `AstNode::is_signed` value.
    AstNodeBuilder &&is_signed(bool v) { return node->is_signed = v, std::move(*this); }

    // Sets `AstNode::is_reg` value.
    AstNodeBuilder &&is_reg(bool v) { return node->is_reg = v, std::move(*this); }

    // Sets `AstNode::range_valid`.
    AstNodeBuilder &&range_valid(bool v) { return node->range_valid = v, std::move(*this); }

    // Convenience range setters

    // Sets `AstNode::range_left`, `AstNode::range_right`, `AstNode::range_valid`.
    AstNodeBuilder &&range(bool v, int left = -1, int right = 0)
    {
        node->range_valid = v;
        node->range_left = left;
        node->range_right = right;
        return std::move(*this);
    }

    // Sets `AstNode::range_left`, `AstNode::range_right`, `AstNode::range_valid = true`.
    AstNodeBuilder &&range(int left, int right) { return range(true, left, right); }

    // Convenience value setters, mainly for constants.

    // Sets node's value.
    // Sets: `AstNode::integer`, `AstNode::is_signed`, `AstNode::bits`.
    AstNodeBuilder &&value(uint32_t v, bool is_signed, int width = 32)
    {
        log_assert(width >= 0);
        node->integer = v;
        node->is_signed = is_signed;
        // `AstNode::mkconst_int` does this too.
        for (int i = 0; i < width; i++) {
            node->bits.push_back((v & 1) ? Yosys::RTLIL::State::S1 : Yosys::RTLIL::State::S0);
            v = v >> 1;
        }
        range(width - 1, 0);
        return std::move(*this);
    }

    // Sets node's value to signed 32 bit integer.
    // Sets: `AstNode::integer`, `AstNode::is_signed`, `AstNode::bits`.
    AstNodeBuilder &&value(int32_t v) { return value(v, true); }

    // Sets node's value to unsigned 32 bit integer.
    // Sets: `AstNode::integer`, `AstNode::is_signed`, `AstNode::bits`.
    AstNodeBuilder &&value(uint32_t v) { return value(v, false); }

    // Type-cast operators used for building.

    operator AstNode *() { return node.release(); }

    operator std::unique_ptr<AstNode>() { return std::move(node); }
};

} // namespace systemverilog_plugin

#endif
