// Core of the FPGA assembly (FASM) output code.
//
// The netlist walker implements the core walking of the netlist and routing
// graph with the intention of emitting the complete implemented design to the
// output FASM file.  Once output, the FASM file is expected to completely
// describe the features required to implement the design in a hardware
// bitstream.
#ifndef FASM_H
#define FASM_H

#include <iostream>
#include <list>
#include <map>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>

#include "netlist_walker.h"
#include "netlist_writer.h"
#include "lut.h"
#include "parameters.h"
#include "route_tree_type.h"

namespace fasm {

// FASM netlist visitor.
//
// This netlist visitor emits FASM features to the provided ostream using
// FASM metadata tags.  See the FASM documentation in docs/utils/fasm.rst
// for a complete list of tags.
//
// High level methodology:
//  - At each top level pb_type, root tile FASM prefix is checked.
//  - At each pb_type, the CLB prefix is build by walking from the child to
//    the root pb_type.
//  - All LUTs are visited and emitted via the fasm_type/fasm_lut tags.
//  - All route through wires are emitted via the same mechanism as LUTs.
//  - All atom's (e.g. leaf pb_types) are visited and have their parameters
//    emitted via fasm_params tags.
//  - All pb_type interconnect's are visited and are emitted via fasm_mux tags.
//  - All pb_type and pb_type mode's are checked for static feature emission
//    via the fasm_features tag.
//
// Once the netlist visitor is done, in finish_impl, the routing graph is
// walked and static features are emitted via the fasm_features tag.
//
// Note that FASM features are incrementally written the ostream as they are
// seen, so the order of FASM output is arbitrary based on the walk order of
// the netlist and routing graph.
class FasmWriterVisitor : public NetlistVisitor {

  public:
      FasmWriterVisitor(std::ostream& f);

  private:
      void visit_top_impl(const char* top_level_name) override;
      void visit_route_through_impl(const t_pb* atom) override;
      void visit_atom_impl(const t_pb* atom) override;
      // clb in visit_clb_impl stands for complex logic block.
      // visit_clb_impl is called on each top-level pb_type used in the design.
      void visit_clb_impl(ClusterBlockId blk_id, const t_pb* clb) override;
      void visit_all_impl(const t_pb_routes &top_pb_route, const t_pb* pb) override;
      void finish_impl() override;

  private:
      void output_fasm_features(const std::string features) const;
      void output_fasm_features(const std::string features, const std::string clb_prefix, const std::string blk_prefix) const;
      void check_features(const t_metadata_dict *meta) const;
      void check_interconnect(const t_pb_routes &pb_route, int inode);
      void check_for_lut(const t_pb* atom);
      void output_fasm_mux(std::string fasm_mux, t_interconnect *interconnect, t_pb_graph_pin *mux_input_pin);
      void walk_routing();
      void walk_route_tree(const t_rt_node *root);
      std::string build_clb_prefix(const t_pb *pb, const t_pb_graph_node* pb_graph_node, bool* is_parent_pb_null) const;
      const LutOutputDefinition* find_lut(const t_pb_graph_node* pb_graph_node);
      void check_for_param(const t_pb *atom);

      // Walk from node to parents and search for a CLB prefix.
      void find_clb_prefix(const t_pb_graph_node *node,
        bool *have_prefix, std::string *clb_prefix) const;

      std::ostream& os_;

      t_pb_graph_node *root_clb_;
      bool current_blk_has_prefix_;
      t_physical_tile_type_ptr blk_type_;
      std::string blk_prefix_;
      std::string clb_prefix_;
      std::map<const t_pb_graph_node *, std::string> clb_prefix_map_;
      ClusterBlockId current_blk_id_;
      std::vector<t_pb_graph_pin**> pb_graph_pin_lookup_from_index_by_type_;
      std::map<const t_pb_type*, std::vector<std::pair<std::string, LutOutputDefinition>>> lut_definitions_;
      std::map<const t_pb_type*, Parameters> parameters_;

      std::map<const std::string, std::string> tags_;
};

} // namespace fasm

#endif  // FASM_H
