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

#include "config.h"
#include "DbeSession.h"
#include "HeapData.h"
#include "StringBuilder.h"
#include "i18n.h"
#include "util.h"
#include "HeapActivity.h"
#include "MetricList.h"
#include "Application.h"
#include "Experiment.h"
#include "DbeView.h"
#include "Exp_Layout.h"
#include "i18n.h"

HeapActivity::HeapActivity (DbeView *_dbev)
{
  dbev = _dbev;
  hDataTotal = NULL;
  hDataObjs = NULL;
  hDataObjsCallStack = NULL;
  hasCallStack = false;
  hDataCalStkMap = NULL;
  hist_data_callstack_all = NULL;
}

void
HeapActivity::reset ()
{
  delete hDataTotal;
  hDataTotal = NULL;
  delete hDataObjsCallStack;
  hDataObjsCallStack = NULL;
  hasCallStack = false;
  hDataObjs = NULL;
  delete hDataCalStkMap;
  hDataCalStkMap = NULL;
  hist_data_callstack_all = NULL;
}

void
HeapActivity::createHistItemTotals (Hist_data *hist_data, MetricList *mlist,
				    Histable::Type hType, bool empty)
{
  int mIndex;
  Metric *mtr;
  Hist_data::HistItem *hi;
  HeapData *hData = NULL;
  if (hDataTotal == NULL)
    {
      hDataTotal = new HeapData (TOTAL_HEAPNAME);
      hDataTotal->setHistType (hType);
      hDataTotal->setStackId (TOTAL_STACK_ID);
      hDataTotal->id = 0;
    }

  hData = new HeapData (hDataTotal);
  hData->setHistType (hType);
  hi = hist_data->append_hist_item (hData);

  Vec_loop (Metric *, mlist->get_items (), mIndex, mtr)
  {
    if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ())
      continue;

    Metric::Type mtype = mtr->get_type ();
    ValueTag vType = mtr->get_vtype ();

    hist_data->total->value[mIndex].tag = vType;
    hi->value[mIndex].tag = vType;
    switch (mtype)
      {
      case BaseMetric::HEAP_ALLOC_BYTES:
	if (!empty)
	  {
	    hist_data->total->value[mIndex].ll = hDataTotal->getAllocBytes ();
	    hi->value[mIndex].ll = hDataTotal->getAllocBytes ();
	  }
	else
	  {
	    hist_data->total->value[mIndex].ll = 0;
	    hi->value[mIndex].ll = 0;
	  }
	break;
      case BaseMetric::HEAP_ALLOC_CNT:
	if (!empty)
	  {
	    hist_data->total->value[mIndex].ll = hDataTotal->getAllocCnt ();
	    hi->value[mIndex].ll = hDataTotal->getAllocCnt ();
	  }
	else
	  {
	    hist_data->total->value[mIndex].ll = 0;
	    hi->value[mIndex].ll = 0;
	  }
	break;
      case BaseMetric::HEAP_LEAK_BYTES:
	if (!empty)
	  {
	    hist_data->total->value[mIndex].ll = hDataTotal->getLeakBytes ();
	    hi->value[mIndex].ll = hDataTotal->getLeakBytes ();
	  }
	else
	  {
	    hist_data->total->value[mIndex].ll = 0;
	    hi->value[mIndex].ll = 0;
	  }
	break;
      case BaseMetric::HEAP_LEAK_CNT:
	if (!empty)
	  {
	    hist_data->total->value[mIndex].ll = hDataTotal->getLeakCnt ();
	    hi->value[mIndex].ll = hDataTotal->getLeakCnt ();
	  }
	else
	  {
	    hist_data->total->value[mIndex].ll = 0;
	    hi->value[mIndex].ll = 0;
	  }
	break;
      default:
	break;
      }
  }
}

void
HeapActivity::computeHistTotals (Hist_data *hist_data, MetricList *mlist)
{
  int mIndex;
  Metric *mtr;
  Vec_loop (Metric *, mlist->get_items (), mIndex, mtr)
  {
    if (!mtr->is_visible () && !mtr->is_tvisible () && !mtr->is_pvisible ())
      continue;

    Metric::Type mtype = mtr->get_type ();
    ValueTag vType = mtr->get_vtype ();

    hist_data->total->value[mIndex].tag = vType;
    switch (mtype)
      {
      case BaseMetric::HEAP_ALLOC_BYTES:
	hist_data->total->value[mIndex].ll = hDataTotal->getAllocBytes ();
	break;
      case BaseMetric::HEAP_ALLOC_CNT:
	hist_data->total->value[mIndex].ll = hDataTotal->getAllocCnt ();
	break;
      case BaseMetric::HEAP_LEAK_BYTES:
	hist_data->total->value[mIndex].ll = hDataTotal->getLeakBytes ();
	break;
      case BaseMetric::HEAP_LEAK_CNT:
	hist_data->total->value[mIndex].ll = hDataTotal->getLeakCnt ();
	break;
      default:
	break;
      }
  }
}

void
HeapActivity::computeHistData (Hist_data *hist_data, MetricList *mlist,
			       Hist_data::Mode mode, Histable *selObj)
{

  Hist_data::HistItem *hi = NULL;

  int numObjs = hDataObjs->size ();
  int numMetrics = mlist->get_items ()->size ();
  for (int i = 0; i < numObjs; i++)
    {
      HeapData *hData = hDataObjs->fetch (i);
      if (mode == Hist_data::ALL)
	hi = hist_data->append_hist_item (hData);
      else if (mode == Hist_data::SELF)
	{
	  if (hData->id == selObj->id)
	    hi = hist_data->append_hist_item (hData);
	  else
	    continue;
	}

      for (int mIndex = 0; mIndex < numMetrics; mIndex++)
	{
	  Metric *mtr = mlist->get_items ()->fetch (mIndex);
	  if (!mtr->is_visible () && !mtr->is_tvisible ()
	      && !mtr->is_pvisible ())
	    continue;

	  Metric::Type mtype = mtr->get_type ();
	  ValueTag vType = mtr->get_vtype ();
	  hi->value[mIndex].tag = vType;
	  switch (mtype)
	    {
	    case BaseMetric::HEAP_ALLOC_BYTES:
	      hi->value[mIndex].ll = hData->getAllocBytes ();
	      break;
	    case BaseMetric::HEAP_ALLOC_CNT:
	      hi->value[mIndex].ll = hData->getAllocCnt ();
	      break;
	    case BaseMetric::HEAP_LEAK_BYTES:
	      hi->value[mIndex].ll = hData->getLeakBytes ();
	      break;
	    case BaseMetric::HEAP_LEAK_CNT:
	      hi->value[mIndex].ll = hData->getLeakCnt ();
	      break;
	    default:
	      break;
	    }
	}
    }
}

Hist_data *
HeapActivity::compute_metrics (MetricList *mlist, Histable::Type type,
			       Hist_data::Mode mode, Histable *selObj)
{
  // it's already there, just return it
  if (mode == Hist_data::ALL && type == Histable::HEAPCALLSTACK
      && hist_data_callstack_all != NULL)
    return hist_data_callstack_all;

  bool has_data = false;
  Hist_data *hist_data = NULL;
  VMode viewMode = dbev->get_view_mode ();
  switch (type)
    {
    case Histable::HEAPCALLSTACK:
      if (!hasCallStack)    // It is not computed yet
	computeCallStack (type, viewMode);

      // computeCallStack() creates hDataObjsCallStack
      // hDataObjsCallStack contains the list of call stack objects
      if (hDataObjsCallStack != NULL)
	{
	  hDataObjs = hDataObjsCallStack;
	  has_data = true;
	}
      else
	has_data = false;

      if (has_data && mode == Hist_data::ALL && hist_data_callstack_all == NULL)
	{
	  hist_data_callstack_all = new Hist_data (mlist, type, mode, true);
	  hist_data = hist_data_callstack_all;
	}
      else if (has_data)
	hist_data = new Hist_data (mlist, type, mode, false);
      else
	{
	  hist_data = new Hist_data (mlist, type, mode, false);
	  createHistItemTotals (hist_data, mlist, type, true);
	  return hist_data;
	}
      break;
    default:
      fprintf (stderr,
	       "HeapActivity cannot process data due to wrong Histable (type=%d) \n",
	       type);
      abort ();
    }

  if (mode == Hist_data::ALL || (mode == Hist_data::SELF && selObj->id == 0))
    createHistItemTotals (hist_data, mlist, type, false);
  else
    computeHistTotals (hist_data, mlist);
  computeHistData (hist_data, mlist, mode, selObj);

  // Determine by which metric to sort if any
  bool rev_sort = mlist->get_sort_rev ();
  int sort_ind = -1;
  int nmetrics = mlist->get_items ()->size ();

  for (int mind = 0; mind < nmetrics; mind++)
    if (mlist->get_sort_ref_index () == mind)
      sort_ind = mind;

  hist_data->sort (sort_ind, rev_sort);
  hist_data->compute_minmax ();

  return hist_data;
}

void
HeapActivity::computeCallStack (Histable::Type type, VMode viewMode)
{
  bool has_data = false;
  reset ();
  uint64_t stackIndex = 0;
  HeapData *hData = NULL;

  delete hDataCalStkMap;
  hDataCalStkMap = new DefaultMap<uint64_t, HeapData*>;

  delete hDataTotal;
  hDataTotal = new HeapData (TOTAL_HEAPNAME);
  hDataTotal->setHistType (type);

  // There is no call stack for total, use the index for id
  hDataTotal->id = stackIndex++;

  // get the list of io events from DbeView
  int numExps = dbeSession->nexps ();

  for (int k = 0; k < numExps; k++)
    {
      // Investigate the performance impact of processing the heap events twice.
      // This is a 2*n performance issue
      dbev->get_filtered_events (k, DATA_HEAPSZ);

      DataView *heapPkts = dbev->get_filtered_events (k, DATA_HEAP);
      if (heapPkts == NULL)
	continue;

      Experiment *exp = dbeSession->get_exp (k);
      long sz = heapPkts->getSize ();
      int pid = 0;
      int userExpId = 0;
      if (sz > 0)
	{
	  pid = exp->getPID ();
	  userExpId = exp->getUserExpId ();
	}
      for (long i = 0; i < sz; ++i)
	{
	  uint64_t nByte = heapPkts->getULongValue (PROP_HSIZE, i);
	  uint64_t stackId = (uint64_t) getStack (viewMode, heapPkts, i);
	  Heap_type heapType = (Heap_type) heapPkts->getIntValue (PROP_HTYPE, i);
	  uint64_t leaked = heapPkts->getULongValue (PROP_HLEAKED, i);
	  int64_t heapSize = heapPkts->getLongValue (PROP_HCUR_ALLOCS, i);
	  hrtime_t packetTimestamp = heapPkts->getLongValue (PROP_TSTAMP, i);
	  hrtime_t timestamp = packetTimestamp - exp->getStartTime () +
		  exp->getRelativeStartTime ();

	  switch (heapType)
	    {
	    case MMAP_TRACE:
	    case MALLOC_TRACE:
	    case REALLOC_TRACE:
	      if (stackId != 0)
		{
		  hData = hDataCalStkMap->get (stackId);
		  if (hData == NULL)
		    {
		      char *stkName = dbe_sprintf (GTXT ("Stack 0x%llx"),
						  (unsigned long long) stackId);
		      hData = new HeapData (stkName);
		      hDataCalStkMap->put (stackId, hData);
		      hData->id = (int64_t) stackId;
		      hData->setStackId (stackIndex);
		      stackIndex++;
		      hData->setHistType (type);
		    }
		}
	      else
		continue;

	      hData->addAllocEvent (nByte);
	      hDataTotal->addAllocEvent (nByte);
	      hDataTotal->setAllocStat (nByte);
	      hDataTotal->setPeakMemUsage (heapSize, hData->getStackId (),
					   timestamp, pid, userExpId);
	      if (leaked > 0)
		{
		  hData->addLeakEvent (leaked);
		  hDataTotal->addLeakEvent (leaked);
		  hDataTotal->setLeakStat (leaked);
		}
	      break;
	    case MUNMAP_TRACE:
	    case FREE_TRACE:
	      if (hData == NULL)
		hData = new HeapData (TOTAL_HEAPNAME);
	      hDataTotal->setPeakMemUsage (heapSize, hData->getStackId (),
					   timestamp, pid, userExpId);
	      break;
	    case HEAPTYPE_LAST:
	      break;
	    }
	  has_data = true;
	}
    }

  if (has_data)
    {
      hDataObjsCallStack = hDataCalStkMap->values ()->copy ();
      hasCallStack = true;
    }
}
