/* Copyright (C) 2021-2024 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.  */

#ifndef _HIST_DATA_H
#define _HIST_DATA_H

// A Hist_data object is used to obtain data used for constructing
// a histogram display.

#include <sys/types.h>

#include <vec.h>
#include <Map.h>
#include <HashMap.h>

#include "dbe_structs.h"
#include "Histable.h"
#include "DerivedMetrics.h"

class DbeLine;
class MetricList;

class Hist_data
{
public:
  friend class DbeView;
  friend class er_print_histogram;
  friend class PathTree;
  friend class DataSpace;
  friend class MemorySpace;
  friend class IOActivity;
  friend class HeapActivity;

  // HistItem contains all the data about a single histogram item.
  struct HistItem
  {
    HistItem (long n);
    ~HistItem ();
    Histable *obj;  // info on the object
    int type;       // annotated src/dis: type
    TValue *value;  // numeric values
    long size;
  };

  enum Hist_status
  {
    SUCCESS = 0,
    NO_DATA
  };

  enum Mode
  {
    ALL,
    CALLERS,
    CALLEES,
    SELF,
    MODL,
    LAYOUT,
    DETAIL
  };

  enum Sort_order
  {
    ASCEND,
    DESCEND
  };

  enum Sort_type
  {
    ALPHA,
    VALUE,
    AUX
  };

  Hist_data (MetricList *, Histable::Type, Mode, bool _viewowned = false);

  virtual ~Hist_data ();
  void dump (char *msg, FILE *f);

  Hist_status
  get_status (void)
  {
    return status;
  }

  // Return the view ownership flag
  bool
  isViewOwned (void)
  {
    return viewowned;
  }

  // Return the total number of items
  long size (void);

  // Append a new HistItem for the specified Histable
  HistItem *append_hist_item (Histable *obj);
  void append_hist_item (HistItem *hi);
  TValue *get_real_value (TValue *res, int met_index, int row);
  TValue *get_value (TValue *res, int met_index, int row);
  TValue *get_value (TValue *res, int met_index, HistItem *hi);
  void print_row(StringBuilder *sb, int row, Metric::HistMetric *hist_metric,
		 const char *mark);
  void print_content (FILE *out_file, Metric::HistMetric *hist_metric, int limit);
  int print_label (FILE *out_file, Metric::HistMetric *hist_metric, int space);
  void update_total (Hist_data::HistItem *new_total);
  void update_max (Metric::HistMetric *hm_tmp);
  void update_legend_width (Metric::HistMetric *hm_tmp);

  // Find an existing HistItem
  HistItem *find_hist_item (Histable *obj);

  // sort the data
  void sort (long ind, bool reverse);

  // resort the data, if metric sort or direction has changed
  void resort (MetricList *mlist);

  // compute minima and maxima
  void compute_minmax (void);

  // fetch() takes a hist item index and returns a ptr to the item
  HistItem *fetch (long index);

  HistItem *
  get_maximums (void)
  {
    return maximum;
  }

  HistItem *
  get_maximums_inc (void)
  {
    return maximum_inc;
  }

  HistItem *
  get_minimums (void)
  {
    return minimum;
  }

  HistItem *
  get_totals (void)
  {
    return total;
  }

  Vector<HistItem*> *
  get_hist_items (void)
  {
    return hist_items;
  }

  void
  set_status (Hist_status st)
  {
    status = st;
  }

  MetricList *
  get_metric_list (void)
  {
    return metrics;
  }

  Map<Histable*, int> *
  get_callsite_mark ()
  {
    return callsite_mark;
  }

  Metric::HistMetric *get_histmetrics ();
  void set_threshold (double proportion);
  bool above_threshold (HistItem *hi);
  double get_percentage (double value, int mindex);
  size_t value_maxlen (int mindex); // Return the drawing length
  size_t time_len (TValue *value, int clock);
  size_t time_maxlen (int mindex, int clock);
  size_t name_len (HistItem *item);
  size_t name_maxlen ();
  HistItem *new_hist_item (Histable *obj, int itype, TValue *value);
  HistItem *update_hist_item (HistItem *hi, TValue *value);
  Vector<uint64_t> *get_object_indices (Vector<int> *selections);

private:

  Metric::HistMetric *hist_metrics;
  Vector<HistItem*> *hist_items;        // Actual histogram values
  HashMap<Histable*, HistItem*>*hi_map; // map: Histable -> HistItem
  Map<Histable*, int>*callsite_mark;
  Hist_status status;
  int nmetrics;             // number of metrics
  MetricList *metrics;
  Histable::Type type;
  Sort_order sort_order;
  Sort_type sort_type;
  int sort_ind;
  bool rev_sort;            // true if sort is reversed

  Mode mode;
  HistItem *gprof_item;     // used for gprof-style info
  Histable *spontaneous;

  // Private state variables
  HistItem *maximum;
  HistItem *minimum;
  HistItem *maximum_inc;
  HistItem *total;
  HistItem *threshold;

  // Perform the sort operation with this function
  static int sort_compare_all (const void *a, const void *b, const void *arg);
  static int sort_compare_dlayout (const void *a, const void *b, const void *arg);
  static int sort_compare (HistItem *hi_1, HistItem *hi_2, Sort_type stype,
			   long ind, Hist_data *hdata);

  // Allocate a new structure of dynamic size
  HistItem *new_hist_item (Histable *obj);

  // Flag indicating whether or not the Hist_data structure
  //	is owned by a DbeView, which has responsibility for
  //	deleting it, or not, in which case the last user deletes it.
  //	XXX this is very ugly, and arises from the inconsistent handling
  //	XXX of the Hist_data structure in various bits of code.
  bool viewowned;
};

// This structure is destined to merge with Hist_data.
// We currently use it to present callstack data such as
// leak and allocation lists.

class DbeInstr;

struct CStack_data
{

  struct CStack_item
  {
    CStack_item (long n);
    ~CStack_item ();
    long count;
    int64_t val;
    Vector<DbeInstr*> *stack;
    TValue *value;      // numeric values
  };

  Vector<CStack_item*> *cstack_items;
  CStack_item *total;

  CStack_item *new_cstack_item ();
  CStack_data (MetricList *);

  long
  size ()
  {
    return cstack_items->size ();
  }

  CStack_item *
  fetch (long i)
  {
    return cstack_items->fetch (i);
  }

  ~CStack_data ()
  {
    cstack_items->destroy ();
    delete cstack_items;
    delete total;
  }

  MetricList *metrics;
};

#endif /* _HIST_DATA_H */
