/* Copyright (C) 2021-2025 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 "util.h"
#include "DbeSession.h"
#include "DbeView.h"
#include "IndexObject.h"
#include "StringBuilder.h"

IndexObject::IndexObject (int _indextype, uint64_t _index)
{
  indextype = _indextype;
  obj = NULL;
  id = _index;
  name = NULL;
  nameIsFinal = false;
}

IndexObject::IndexObject (int _indextype, Histable *_obj)
{
  indextype = _indextype;
  obj = _obj;
  id = obj ? obj->id : (uint64_t) - 1;
  name = NULL;
  nameIsFinal = false;
}

void
IndexObject::set_name (char * other_name)
{
  if (name == NULL)
    {
      name = other_name;
      nameIsFinal = true;
    }
}

static uint64_t
extractExpgrid (uint64_t id)
{
  return (id >> IndexObject::INDXOBJ_EXPGRID_SHIFT)
	  & IndexObject::INDXOBJ_EXPGRID_MASK;
}

static uint64_t
extractExpid (uint64_t id)
{
  return (id >> IndexObject::INDXOBJ_EXPID_SHIFT)
	  & IndexObject::INDXOBJ_EXPID_MASK;
}

static uint64_t
extractPayload (uint64_t id)
{
  return (id >> IndexObject::INDXOBJ_PAYLOAD_SHIFT)
	  & IndexObject::INDXOBJ_PAYLOAD_MASK;
}

static void
printCompareLabel (StringBuilder *sb, uint64_t grpId);

static bool
printThread (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id)
{
  uint64_t proc = extractExpid (id);
  uint64_t thrid = extractPayload (id);
  bool isFinal = true;
  bool hasJava = false;
  bool javaThread = false;
  if (ctx)
    {
      if (ctx->dview && ctx->dview->getProp (PROP_JTHREAD))
	{
	  hasJava = true;
	  uint64_t tstamp = ctx->dview->getLongValue (PROP_TSTAMP, ctx->eventId);
	  JThread *jthread = ctx->exp->map_pckt_to_Jthread (thrid, tstamp);
	  if (jthread != JTHREAD_NONE && jthread != JTHREAD_DEFAULT)
	    {
	      sbIn->appendf (GTXT ("Process %llu, Thread %llu, JThread %llu \'%s\', Group \'%s\', Parent \'%s\'"),
			     (unsigned long long) proc,
			     (unsigned long long) thrid,
			     (unsigned long long) jthread->jthr_id,
			     get_str(jthread->name, ""),
			     get_str(jthread->group_name, ""),
			     get_str(jthread->parent_name, ""));
	      javaThread = true;
	    }
	}
    }
  if (!javaThread)
    {
      sbIn->appendf (GTXT ("Process %llu, Thread %llu"),
		     (unsigned long long) proc, (unsigned long long) thrid);
      if (hasJava)
	// sometimes threads start as native and later become Java; keep checking
	isFinal = false;
    }
  if (ctx && ctx->dbev && ctx->dbev->comparingExperiments ())
    {
      Vector <Histable *> *v = ctx->exp->get_comparable_objs ();
      int st = 0;
      for (long i = 0, sz = VecSize (v); i < sz; i++)
	{
	  Experiment *exp = (Experiment *) v->get (i);
	  if (exp)
	    {
	      if (st == 0)
		{
		  st = 1;
		  continue;
		}
	      sbIn->appendf (GTXT (" [ Group %llu  Process %llu ]"),
			     (unsigned long long) exp->groupId - 1,
			     (unsigned long long) exp->getUserExpId ());
	    }
	}
    }
  return isFinal;
}

static bool
printProcess (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id)
{
  uint64_t proc = id;
  if (ctx && ctx->exp)
    {
      int st = 0;
      if (ctx->dbev && ctx->dbev->comparingExperiments ())
	{
	  Vector <Histable *> *v = ctx->exp->get_comparable_objs ();
	  for (long i = 0, sz = VecSize (v); i < sz; i++)
	    {
	      Experiment *exp = (Experiment *) v->get (i);
	      if (exp)
		{
		  if (st == 0)
		    {
		      st = 1;
		      sbIn->appendf (GTXT ("%s, Process %3llu, PID %llu"),
				 get_str (exp->utargname, GTXT ("(unknown)")),
				     (unsigned long long) proc,
				     (unsigned long long) exp->getPID ());
		      continue;
		    }
		  sbIn->appendf (GTXT (" [ Group %llu,  Process %llu, PID %llu ]"),
				 (unsigned long long) exp->groupId - 1,
				 (unsigned long long) exp->getUserExpId (),
				 (unsigned long long) exp->getPID ());
		}
	    }
	}
      if (st == 0)
	sbIn->appendf (GTXT ("%s, Process %3llu, PID %llu"),
		       get_str (ctx->exp->utargname, GTXT ("(unknown)")),
		       (unsigned long long) proc,
		       (unsigned long long) ctx->exp->getPID ());
    }
  else
    sbIn->appendf (GTXT ("Process %3llu"), (unsigned long long) proc);
  return true; //name is final
}

static bool
printExperiment (StringBuilder *sbIn, Expression::Context * ctx, uint64_t id)
{
  uint64_t grpId = extractExpgrid (id);
  uint64_t expid = extractExpid (id);
  if (ctx && ctx->dbev->comparingExperiments ())
    printCompareLabel (sbIn, grpId);
  if (ctx)
    {
      Experiment *hasFounder = ctx->exp->founder_exp;
      int pid = ctx->exp->getPID ();
      uint64_t founderExpid;
      if (hasFounder)
	founderExpid = hasFounder->getUserExpId ();
      else
	founderExpid = expid;
      sbIn->appendf (GTXT ("Base Experiment %llu, Process %llu, PID %llu, %s"),
		     (unsigned long long) founderExpid,
		     (unsigned long long) expid,
		     (unsigned long long) pid,
		     get_str (ctx->exp->utargname, GTXT ("(unknown)")));
    }
  else
    sbIn->appendf (GTXT ("Process %llu"), (unsigned long long) expid);
  return true; // name is final
}

void
IndexObject::set_name_from_context (Expression::Context * ctx)
{
  if (name != NULL)
    if (nameIsFinal && strstr (name, GTXT ("(unknown)")) == NULL)
      return;
  if (ctx == NULL || ctx->dview == NULL || ctx->dbev == NULL)
    return;
  StringBuilder sb;
  switch (indextype)
    {
    case INDEX_THREADS:
      nameIsFinal = printThread (&sb, ctx, id);
      break;
    case INDEX_PROCESSES:
      nameIsFinal = printProcess (&sb, ctx, id);
      break;
    case INDEX_EXPERIMENTS:
      nameIsFinal = printExperiment (&sb, ctx, id);
      break;
    default:
      name = NULL;
      return;
    }
  if (sb.length ())
    name = sb.toString ();
}

static void
printCompareLabel (StringBuilder *sbIn, uint64_t grpId)
{
  static const char *labels[] = {"", GTXT ("Baseline"), GTXT ("Comparison")};
  static int length;
  if (!length)
    {
      length = strlen (labels[1]);
      int length2 = strlen (labels[2]);
      if (length < length2)
	length = length2;
      length += 5; // for open/close brace and grpId number and spaces
    }
  char *s = NULL;
  if (grpId != 0)
    {
      if (grpId <= 2)
	s = dbe_sprintf ("[%s]", labels[grpId]);
      else
	s = dbe_sprintf ("[%s-%llu]", labels[2],
			 (unsigned long long) (grpId - 1));
    }
  sbIn->appendf ("%-*s", length, get_str (s, ""));
  free (s);
}

char *
IndexObject::get_name (NameFormat fmt)
{
  if (name == NULL)
    {
      StringBuilder sb;
      int64_t upper;
      int64_t num1;
      int64_t num2;
      switch (indextype)
	{
	case INDEX_THREADS:
	  printThread (&sb, NULL, id);
	  break;

	case INDEX_CPUS:
	  sb.sprintf (GTXT ("CPU %llu"), (unsigned long long) id);
	  break;

	case INDEX_SAMPLES:
	  sb.sprintf (GTXT ("Sample %llu"), (unsigned long long) id);
	  break;

	case INDEX_GCEVENTS:
	  if (id == 0)
	    {
	      sb.sprintf (GTXT ("Not in any GCEvent"));
	    }
	  else
	    {
	      sb.sprintf (GTXT ("GCEvent %llu"), (unsigned long long) id);
	    }
	  break;

	case INDEX_SECONDS:
	  sb.sprintf (GTXT ("Second of execution %llu"), (unsigned long long) id);
	  break;

	case INDEX_PROCESSES:
	  printProcess (&sb, NULL, id);
	  break;

	case INDEX_EXPERIMENTS:
	  printExperiment (&sb, NULL, id);
	  break;
	case INDEX_BYTES:
	  upper = id;
	  if (id == -1)
	    {
	      break;
	    }
	  if (id % 2 == 1 && id > 1)
	    {
	      upper = id - 1;
	      if (upper >= 1099511627776)
		{
		  num1 = upper / 1099511627776;
		  sb.sprintf (GTXT (">= %3llu TB"), (unsigned long long) num1);
		}
	      else
		{
		  // XXXX do nothing, this should not happen
		}
	    }
	  else
	    {
	      if (upper >= 1099511627776)
		{
		  num1 = upper / 1099511627776;
		  num2 = num1 / 4;
		  if (num2)
		    {
		      sb.sprintf (GTXT ("%3lluTB < n <= %3lluTB"), (unsigned long long) num2, (unsigned long long) num1);
		    }
		  else
		    {
		      sb.sprintf (GTXT ("256GB < n <= %3lluTB"), (unsigned long long) num1);
		    }
		}
	      else if (upper >= 1073741824)
		{
		  num1 = upper / 1073741824;
		  num2 = num1 / 4;
		  if (num2)
		    {
		      sb.sprintf (GTXT ("%3lluGB < n <= %3lluGB"), (unsigned long long) num2, (unsigned long long) num1);
		    }
		  else
		    {
		      sb.sprintf (GTXT ("256MB < n <= %3lluGB"), (unsigned long long) num1);
		    }
		}
	      else if (upper >= 1048576)
		{
		  num1 = upper / 1048576;
		  num2 = num1 / 4;
		  if (num2)
		    {
		      sb.sprintf (GTXT ("%3lluMB < n <= %3lluMB"), (unsigned long long) num2, (unsigned long long) num1);
		    }
		  else
		    {
		      sb.sprintf (GTXT ("256KB < n <= %3lluMB"), (unsigned long long) num1);
		    }
		}
	      else if (upper >= 1024)
		{
		  num1 = upper / 1024;
		  num2 = num1 / 4;
		  if (num2)
		    {
		      sb.sprintf (GTXT ("%3lluKB < n <= %3lluKB"), (unsigned long long) num2, (unsigned long long) num1);
		    }
		  else
		    {
		      sb.sprintf (GTXT ("  256 < n <= %3lluKB"), (unsigned long long) num1);
		    }
		}
	      else if (upper > 0)
		{
		  num1 = upper;
		  num2 = num1 / 4;
		  if (num1 == 1)
		    {
		      sb.sprintf (GTXT ("    1 Byte"));
		    }
		  else
		    {
		      sb.sprintf (GTXT ("%5llu < n <= %5llu Bytes"), (unsigned long long) num2, (unsigned long long) num1);
		    }
		}
	      else if (upper == 0)
		{
		  sb.sprintf (GTXT ("    0 Bytes"));
		}
	      else
		{
		  sb.sprintf (GTXT ("<No Data>"));
		}
	    }
	  break;
	case INDEX_DURATION:
	  if (id == -1)
	    {
	      break;
	    }

	  if (id > 10000000000000)
	    {
	      sb.sprintf (GTXT ("n > 10000s"));
	    }
	  else if (id > 1000000000000)
	    {
	      sb.sprintf (GTXT ("1000s < n <= 10000s"));
	    }
	  else if (id > 100000000000)
	    {
	      sb.sprintf (GTXT (" 100s < n <= 1000s"));
	    }
	  else if (id > 10000000000)
	    {
	      sb.sprintf (GTXT ("  10s < n <=  100s"));
	    }
	  else if (id > 1000000000)
	    {
	      sb.sprintf (GTXT ("   1s < n <=   10s"));
	    }
	  else if (id > 100000000)
	    {
	      sb.sprintf (GTXT ("100ms < n <=    1s"));
	    }
	  else if (id > 10000000)
	    {
	      sb.sprintf (GTXT (" 10ms < n <= 100ms"));
	    }
	  else if (id > 1000000)
	    {
	      sb.sprintf (GTXT ("  1ms < n <=  10ms"));
	    }
	  else if (id > 100000)
	    {
	      sb.sprintf (GTXT ("100us < n <=   1ms"));
	    }
	  else if (id > 10000)
	    {
	      sb.sprintf (GTXT (" 10us < n <= 100us"));
	    }
	  else if (id > 1000)
	    {
	      sb.sprintf (GTXT ("  1us < n <=  10us"));
	    }
	  else if (id > 0)
	    {
	      sb.sprintf (GTXT ("   0s < n <=   1us"));
	    }
	  else if (id == 0)
	    {
	      sb.sprintf (GTXT ("   0s"));
	    }
	  else
	    {
	      sb.sprintf (GTXT ("<No Data>"));
	    }
	  break;

	  // Custom index objects
	default:
	  if (obj)
	      sb.sprintf (GTXT ("%s from %s"),
			  dbeSession->getIndexSpaceDescr (indextype), obj->get_name (fmt));
	  else
	    {
	      IndexObjType_t *indexObj = dbeSession->getIndexSpace (indextype);
	      if (indexObj->memObj)
		{
		  if (strcasecmp (indexObj->name, NTXT ("Memory_page_size")) == 0)
		    {
		      if (id == 0)
			  sb.append (GTXT ("<Unknown>"));
		      else
			  sb.sprintf (NTXT ("%s 0x%16.16llx (%llu)"), indexObj->name,
				      (unsigned long long) id, (unsigned long long) id);
		    }
		  else if (strcasecmp (indexObj->name, NTXT ("Memory_in_home_lgrp")) == 0)
		    {
		      if (id == 0 || id == 1)
			  sb.sprintf (NTXT ("%s: %s"), indexObj->name,
				      id == 1 ? GTXT ("True") : GTXT ("False"));
		      else
			  sb.sprintf (NTXT ("%s %s (0x%llx"), indexObj->name,
				      GTXT ("<Unknown>"), (unsigned long long) id);
		    }
		  else if (strcasecmp (indexObj->name, NTXT ("Memory_lgrp")) == 0)
		    {
		      if (id == 0)
			  sb.append (GTXT ("<Unknown>"));
		      else
			  sb.sprintf (NTXT ("%s %llu"), indexObj->name, (unsigned long long) id);
		    }
		  else
		      sb.sprintf (NTXT ("%s 0x%16.16llx"), indexObj->name, (unsigned long long) id);
		}
	      else
		  sb.sprintf ("%s 0x%16.16llx (%llu)", indexObj->name,
			      (unsigned long long) id, (unsigned long long) id);
	    }
	}
      name = sb.toString ();
      nameIsFinal = true;
    }
  return name;
}

bool
IndexObject::requires_string_sort ()
{
  if (indextype == INDEX_PROCESSES || indextype >= INDEX_LAST)
    return true;
  return false;
}

Histable *
IndexObject::convertto (Histable_type type, Histable *ext)
{
  if (type == INDEXOBJ)
    return this;
  if (obj)
    return obj->convertto (type, ext);
  return NULL;
}

IndexObjType_t::IndexObjType_t ()
{
  type = 0;
  name = NULL;
  i18n_name = NULL;
  index_expr_str = NULL;
  index_expr = NULL;
  mnemonic = 0;
  short_description = NULL;
  long_description = NULL;
  memObj = NULL;
}

IndexObjType_t::~IndexObjType_t ()
{
  free (name);
  free (i18n_name);
  free (index_expr_str);
  delete index_expr;
  free (short_description);
  free (long_description);
}
