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

#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);
}
