/* Copyright (C) 2021 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/* The DbeSession class is instantiated by a DbeApplication, and contains
 *	all the data referring to a set of loaded experiments
 *
 *	It manages a set of tables for the Experiments, for the LoadObjects
 *	referenced in them, and for the other objects representing the
 *	elements in the program hierarchy that can have metrics associated
 *	with them.  It also has a master list of all the metrics available
 *	from all the loaded experiments.
 *
 *	It gets an instance of the Settings class, instantiated as a copy
 *	of the one in the DbeApplication that instantiated the DbeSession.
 *
 *	In addition, it manages a vector of DbeView's (q.v.); each DbeView
 *	represents a window into the DbeSession, and has its own set of
 *	Settings, and FilterSets for the Experiments, and is the access point
 *	for all processed data.
 */

#ifndef _DBESESSION_H
#define _DBESESSION_H


#include <stdio.h>
#include "dbe_structs.h"
#include "vec.h"
#include "Hist_data.h"
#include "Histable.h"
#include "BaseMetric.h"
#include "BaseMetricTreeNode.h"
#include "MemorySpace.h"
#include "hwcentry.h"
#include "dbe_types.h"
#include "Settings.h"
#include "HashMap.h"
#include "Table.h"
#include "Experiment.h"

class DbeSession;
class Experiment;
class Expression;
class ExpGroup;
class Function;
class JMethod;
class Histable;
class DbeView;
class Module;
class LoadObject;
class DataObject;
class SourceFile;
class Settings;
class StringBuilder;
class UserLabel;
class DbeFile;
class DbeJarFile;
class FileData;
class HeapData;
template <typename ITEM> class DbeSyncMap;
template <class ITEM> class Vector;

struct DispTab;
struct List;
struct Countable;
class IndexObjType_t;

typedef struct
{
  char *path;
  Experiment *exp;
  DbeSession *ds;
  bool read_ahead;
} exp_ctx;

class DbeSession
{
public:
  DbeSession (Settings *_settings, bool _ipc_mode, bool _rdt_mode);
  ~DbeSession ();

  void reset ();
  void reset_data ();

  void
  set_interactive (bool _interactive)
  {
    interactive = _interactive;
  }

  bool
  is_interactive ()
  {
    return interactive;
  }

  bool is_datamode_available ();
  bool is_leaklist_available ();
  bool is_heapdata_available ();
  bool is_iodata_available ();
  bool is_racelist_available ();
  bool is_deadlocklist_available ();
  bool is_timeline_available ();
  bool is_ifreq_available ();
  bool is_omp_available ();
  bool has_java ();
  bool has_ompavail ();

  // XXX  get_clock should be removed, to support cpus with different clocks
  // XXX    means reworking time-convertible HWC code
  int get_clock (int id);

  // Access functions for DbeView's
  int createView ();
  int createView (int index, int cloneindex);
  DbeView *getView (int index);
  void dropView (int index);

  // Access functions controlling the experiment list
  Vector<char*> *get_group_or_expt (char *path); // load an experiment or group

  void open_experiment (Experiment *exp, char *path);
  Experiment *get_exp (int exp_ind);
  Vector<Vector<char*>*> *getExperimensGroups ();
  char *setExperimentsGroups (Vector<Vector<char*>*> *groups);
  char *drop_experiment (int exp_ind);
  int find_experiment (char *path);

  int
  nexps ()
  {
    return exps->size ();
  }
  int ngoodexps ();

  // Access functions controlling the DataObject list
  DataObject *createDataObject ();
  DataObject *createDataObject (DataObject *d, DataObject *p = NULL);
  DataObject *createMasterDataObject (DataObject *);
  Vector<DataObject*> *get_dobj_elements (DataObject *);

  DataObject *
  get_Total_DataObject ()
  {
    return d_total;
  };

  DataObject *
  get_Unknown_DataObject ()
  {
    return d_unknown;
  };

  DataObject *
  get_Scalars_DataObject ()
  {
    return d_scalars;
  };

  DataObject *find_dobj_by_name (char *dobj_name);
  DataObject *find_dobj_match (DataObject *dobj);
  DataObject *find_dobj_master (DataObject *dobj);

  int
  ndobjs ()
  {
    return dobjs->size ();
  }

  // check if no -xhwcprof should be ignored
  bool
  check_ignore_no_xhwcprof ()
  {
    return settings->get_ignore_no_xhwcprof ();
  };

  // check if FS warning should be comment, or real warning
  bool
  check_ignore_fs_warn ()
  {
    return settings->get_ignore_fs_warn ();
  };

  // Access functions controlling the LoadObject list
  DbeSyncMap<LoadObject> *loadObjMap;
  void append (LoadObject *lobj);
  LoadObject *createLoadObject (const char *nm, int64_t cksum = 0);
  LoadObject *createLoadObject (const char *nm, const char *runTimePath, DbeFile *df);

  Vector<LoadObject *> *
  get_LoadObjects ()
  {
    return lobjs;
  };

  void dobj_updateHT (DataObject *dobj);
  LoadObject *get_Total_LoadObject ();
  Vector<LoadObject*> *get_text_segments ();
  LoadObject *get_Unknown_LoadObject ();
  LoadObject *find_lobj_by_name (const char *lobj_name, int64_t cksum = 0);

  // Access functions controlling the Tab list
  Vector<DispTab*> *
  get_TabList ()
  {
    return settings->get_TabList ();
  };

  Vector<bool> *
  get_MemTabList ()
  {
    return settings->get_MemTabState ();
  };

  void mobj_define (MemObjType_t *);

  // Access functions controlling metrics
  BaseMetric *find_base_reg_metric (char *mcmd);
  Vector<BaseMetric*> *get_base_reg_metrics (); // excludes comparison (expr) variants

  Vector<BaseMetric*> *
  get_all_reg_metrics ()
  {
    return reg_metrics;     // includes comparison (expr) variants
  };

  BaseMetricTreeNode *get_reg_metrics_tree ();
  BaseMetric *register_metric_expr (BaseMetric::Type type, char *aux, char *expr_spec);
  BaseMetric *register_metric (BaseMetric::Type type);
  BaseMetric *register_metric (char *name, char *username, char *_def);
  BaseMetric *register_metric (Hwcentry *ctr, const char* cmdname, const char* username);
  void drop_metric (BaseMetric *);
  Module *createModule (LoadObject *lo, const char *nm);
  Module *createUnknownModule (LoadObject *lo);
  Module *createClassFile (char *className);
  DbeFile *getDbeFile (char *filename, int filetype);
  SourceFile *get_Unknown_Source ();
  SourceFile *createSourceFile (const char *path);
  Histable *createHistObject (Histable::Type);
  Function *createFunction ();
  Function *create_hide_function (LoadObject *lo);
  Function *get_Total_Function ();
  Function *get_Unknown_Function ();
  Function *get_JUnknown_Function ();
  Function *get_jvm_Function ();
  LoadObject *get_OMP_LoadObject ();
  Function *get_OMP_Function (int);
  JMethod *createJMethod ();
  Histable *createIndexObject (int idxtype, int64_t idx);
  Histable *createIndexObject (int idxtype, Histable *hobj);

  enum SpecialFunction
  {
    TruncatedStackFunc,
    FailedUnwindFunc,
    LastSpecialFunction
  };
  Function *getSpecialFunction (SpecialFunction);

  Histable *
  findObjectById (uint64_t _id)
  {
    long id = (long) _id;
    return (id >= 0 && id < objs->size ()) ? objs->fetch (id) : NULL;
  }

  Histable *findObjectById (Histable::Type type, int subtype, uint64_t id);

  // Other access functions
  bool find_obj (FILE *dis_file, FILE *inp_file, Histable *&obj, char *name,
		 const char *sel, Histable::Type type, bool xdefault);
  int ask_which (FILE *dis_file, FILE *inp_file, Vector<Histable*> *list, char *name);
  LoadObject *map_NametoLoadObject (char *name, Vector<Histable*> *, int which);
  Module *map_NametoModule (char *name, Vector<Histable*> *, int which);
  Function *map_NametoFunction (char *, Vector<Histable*> *, const char *);
  DataObject *map_NametoDataObject (char *name, Vector<Histable*> *, int which);
  bool match_FName (char *name, Function *func);

  // Functions to convert a string to all matching Functions/DataObjects
  Vector<Function *> *match_func_names (const char *ustr, Histable::NameFormat nfmt);
  Vector<DataObject *> *match_dobj_names (char *);

  // Functions to convert a string to all matching JThreads
  Vector<JThread*> *match_java_threads (char *ustr, int matchParent,
					Vector<uint64_t> * &grids,
					Vector<uint64_t> * &expids);
  // Function to convert a string to all matching File names
  Vector<FileData *> *match_file_names (char *ustr, Histable::NameFormat nfmt);

  // Access functions concerning the search path
  Vector<char*> *
  get_search_path ()
  {
    return search_path;
  }

  Vector<DbeFile*>*get_classpath ();
  void set_search_path (Vector<char*> *path, bool reset);
  void set_search_path (char *lpath, bool reset);
  bool add_classpath (char *path);
  bool add_path (char *path);
  void set_pathmaps (Vector<pathmap_t*> *newPathMap);
  Vector<pathmap_t*> *get_pathmaps ();

  // functions to aid debugging
  void dump_stacks (FILE *);
  void dump_dataobjects (FILE *);
  void dump_segments (FILE *);
  void dump_map (FILE *);

  // Find dynamic property by name
  int registerPropertyName (const char *name);
  int getPropIdByName (const char *name);
  char* getPropName (int propId);
  char* getPropUName (int propId);

  Vector<UserLabel*> *userLabels; // List of er_labels
  UserLabel *findUserLabel (const char *name);
  DbeJarFile *get_JarFile (const char *name);
  void append (UserLabel *lbl);
  void append (SourceFile *sf);
  void append (Experiment *exp);
  void append (Hwcentry *exp);
  void set_need_refind ();

  // Find user defined object by name
  Expression *findObjDefByName (const char *);
  void get_filter_keywords (Vector<void*> *res);

  // Get the Settings class object
  Settings *
  get_settings ()
  {
    return settings;
  }

  // static members, used to define or fetch the various IndexSpaces
  Vector<void*> *getIndxObjDescriptions (void);
  Vector<void*> *getCustomIndxObjects (void);
  char *indxobj_define (const char *, char *, const char *, char *, char *);
  char *getIndexSpaceName (int index);
  char *getIndexSpaceDescr (int index);
  Expression *getIndexSpaceExpr (int index);
  char *getIndexSpaceExprStr (int index);
  int findIndexSpaceByName (const char *mname);
  void removeIndexSpaceByName (const char *mname);
  IndexObjType_t *getIndexSpace (int index);
  IndexObjType_t *findIndexSpace (const char *mname);
  Expression *ql_parse (const char *expr_spec);
  BaseMetric *find_metric (BaseMetric::Type type, const char *cmd, const char *expr_spec = NULL);
  static void dump (char *msg, Vector<Metric*> *mlist);
  static void dump (char *msg, Vector<BaseMetric*> *mlist);
  static Platform_t platform;               // Sparc, Intel
  Vector<ExpGroup *> *expGroups;
  HashMap<char*, LoadObject *> *comp_lobjs; // list of comparable LoadObjects
  HashMap<char*, DbeLine *> *comp_dbelines; // list of comparable DbeLines
  HashMap<char*, SourceFile*>*comp_sources; // list of comparable SourceFiles
  char *localized_SP_UNKNOWN_NAME;

  void
  set_lib_visibility_used ()
  {
    lib_visibility_used = true;
  }

  bool
  is_lib_visibility_used ()
  {
    return lib_visibility_used;
  }

  void unlink_tmp_files ();
  char *get_tmp_file_name (const char *nm, bool for_java);

  Vector<char *> *tmp_files;
  int status_ompavail;
  int archive_mode;
  bool ipc_mode;
  bool rdt_mode;

  // data and methods concerning the machine model
  //    methods are in source file MachineModel.cc
  Vector<char*> *list_mach_models (); // scan . and system lib directory for models
  char *load_mach_model (char *);

  char *
  get_mach_model ()
  {
    return dbe_strdup (mach_model_loaded);
  };
  Vector<SourceFile *> *get_sources ();

private:
  void init ();
  void check_tab_avail ();
  bool add_path (char *path, Vector<char*> *pathes);
  Experiment *createExperiment ();

  // Divide the regular createExperiment into two parts -
  // Part1 creates just the Experiment data structure
  // Part2 updates related fields and vectors
  Experiment *createExperimentPart1 ();
  void createExperimentPart2 (Experiment *exp);

  Histable *findIndexObject (int idxtype, uint64_t idx);
  void append_mesgs (StringBuilder *sb, char *path, Experiment *exp);
  static void insert_metric (BaseMetric *mtr, Vector<BaseMetric*> *mlist);
  void update_metric_tree (BaseMetric *m);

  char *find_mach_model (char *);   // fine machine model file by name
  Vector<Experiment*> *exps;        // Master list of experiments
  Vector<Histable*> *objs;          // Master list of Functions,Modules,Segments
  Vector<DataObject*> *dobjs;       // Master list of DataObjects
  Vector<LoadObject*> *lobjs;       // Auxiliary list of LoadObjects
  Vector<Hwcentry*> *hwcentries;
  Vector<HashMap<uint64_t, Histable*>*> *idxobjs; // Master list of IndexObjects
  HashMap<char*, SourceFile*> *sourcesMap;  // list of Source which were not archived
  Vector<SourceFile*> *sources;         // list of SourceFiles
  Map<const char*, DbeJarFile*>*dbeJarFiles;
  Vector<Countable*> *metrics;
  Vector<BaseMetric*> *reg_metrics;     // Master list of BaseMetrics
  BaseMetricTreeNode* reg_metrics_tree; // Hierarchy of BaseMetrics
  Vector<char*> *search_path;
  Vector<char*> *classpath;
  Vector<DbeFile*> *classpath_df;
  Map<const char*, DbeFile*>*dbeFiles;
  Vector<DbeView*> *views;              // Master list of DbeViews
  bool interactive;                     // interactive mode
  bool lib_visibility_used;
  LoadObject *lo_total;                 // Total LoadObject
  Function *f_total;                    // Total function
  LoadObject *lo_unknown;               // Unknown LoadObject
  Function *f_unknown;                  // Unknown function
  SourceFile *sf_unknown;               // Unknown source file
  Function *f_jvm;                      // pseudo-function <JVM-System>
  Vector<Function*> *f_special;         // pseudo-functions
  Function *j_unknown;                  // pseudo-function <no Java callstack>
  LoadObject *lo_omp;                   // OMP LoadObject (libmtsk)
  Vector<Function*> *omp_functions;     // OMP-overhead, etc.
  DataObject *d_unknown;                // Unknown dataobject
  DataObject *d_scalars;                // Scalars dataobject
  DataObject *d_total;                  // Total dataobject
  List **dnameHTable;                   // DataObject name hash table
  Settings *settings;                   // setting/defaults structure
  Vector<IndexObjType_t*> *dyn_indxobj; // Index Object definitions
  int dyn_indxobj_indx;
  int dyn_indxobj_indx_fixed;

  void propNames_name_store (int propId, const char *propName);
  void propNames_name_store (int propId, const char *propName,
			     const char *propUName, VType_type vType, int flags);
  char* propNames_name_fetch (int propId);
  Vector<PropDescr*> *propNames;
  char *defExpName;
  int user_exp_id_counter;
  char *mach_model_loaded;
  char *tmp_dir_name;
};

// For now, there's only one, so keep its pointer
extern DbeSession *dbeSession;

extern Vector<char *> *split_str (char *str, char delimiter);
#endif  /* _DBESESSION_H */
