/* 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 <assert.h>
#include <string.h>
#include <ctype.h>

#include "util.h"
#include "DbeSession.h"
#include "Application.h"
#include "DataObject.h"
#include "Module.h"
#include "debug.h"

DataObject::DataObject ()
{
  name = NULL;
  parent = NULL;
  master = NULL;
  _unannotated_name = NULL;
  _typename = NULL;
  _instname = NULL;
  scope = NULL;
  EAs = new Vector<DbeEA*>;
  size = 0;
  offset = (uint64_t) (-1);
}

DataObject::~DataObject ()
{
  free (_unannotated_name);
  free (_typename);
  free (_instname);
  EAs->destroy ();
  delete EAs;
}

// get_addr() doesn't return an actual address for a DataObject
// but rather synthesises an address-like identifier tuple.
// XXXX since an aggregate and its first element have identical tuples
// may need to arrange for special-purpose sorting "by address"
uint64_t
DataObject::get_addr ()
{
  uint64_t addr;
  if (parent && parent->get_typename ())
    addr = MAKE_ADDRESS (parent->id, offset);   // element
  else if (parent)
    addr = MAKE_ADDRESS (parent->id, id) | 0x8000000000000000ULL; // Scalar, Unknown
  else if (id == dbeSession->get_Scalars_DataObject ()->id)
    addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL;    // Scalar aggregate
  else if (id == dbeSession->get_Unknown_DataObject ()->id)
    addr = MAKE_ADDRESS (id, 0) | 0x8000000000000000ULL;    // Unknown aggregate
  else
    addr = MAKE_ADDRESS (id, 0);     // aggregate
  return addr;
}

Histable *
DataObject::convertto (Histable_type type, Histable *)
{
  return type == DOBJECT ? this : NULL;
}

char
DataObject::get_offset_mark ()
{
  enum
  {
    blocksize = 32
  };

  if (size == 0 || offset == -1)
    return '?';     // undefined
  if (size > blocksize)
    return '#';     // requires multiple blocks
  if (size == blocksize && (offset % blocksize == 0))
    return '<';     // fits block entirely
  if (offset % blocksize == 0)
    return '/';     // starts block
  if ((offset + size) % blocksize == 0)
    return '\\';    // closes block
  if (offset / blocksize == ((offset + size) / blocksize))
    return '|';     // inside block
  return 'X';       // crosses blocks unnecessarily
}

char *
DataObject::get_offset_name ()
{
  char *offset_name;
  if (parent && parent->get_typename ()) // element
    offset_name = dbe_sprintf (GTXT ("%c%+6lld .{%s %s}"),
			       get_offset_mark (), (long long) offset,
			       _typename ? _typename : GTXT ("NO_TYPE"),
			       _instname ? _instname : GTXT ("-")); // "NO_NAME"
  else if ((offset != -1) && (offset > 0)) // filler
    offset_name = dbe_sprintf (GTXT ("%c%+6lld %s"), get_offset_mark (),
			       (long long) offset, get_name ());
  else if (parent) // Scalar/Unknown element
    offset_name = dbe_sprintf (GTXT ("        .%s"), get_unannotated_name ());
  else // aggregate
    offset_name = dbe_strdup (get_name ());
  return offset_name;
}

void
DataObject::set_dobjname (char *type_name, char *inst_name)
{
  _unannotated_name = _typename = _instname = NULL;
  if (inst_name)
    _instname = dbe_strdup (inst_name);

  char *buf;
  if (parent == dbeSession->get_Scalars_DataObject ())
    {
      if (type_name)
	_typename = dbe_strdup (type_name);
      _unannotated_name = dbe_sprintf (NTXT ("{%s %s}"), type_name,
				       inst_name ? inst_name : NTXT ("-"));
      buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
    }
  else if (parent == dbeSession->get_Unknown_DataObject ())
    {
      _unannotated_name = dbe_strdup (type_name);
      buf = dbe_sprintf (NTXT ("%s.%s"), parent->get_name (), _unannotated_name);
    }
  else
    {
      if (type_name)
	_typename = dbe_strdup (type_name);
      if (parent && parent->get_typename ())
	buf = dbe_sprintf (NTXT ("%s.{%s %s}"),
			   parent->get_name () ? parent->get_name () : NTXT ("ORPHAN"),
			   type_name ? type_name : NTXT ("NO_TYPE"),
			   inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
      else
	buf = dbe_sprintf (NTXT ("{%s %s}"),
			   type_name ? type_name : NTXT ("NO_TYPE"),
			   inst_name ? inst_name : NTXT ("-")); // "NO_NAME"
    }
  name = buf;
  dbeSession->dobj_updateHT (this);
}

void
DataObject::set_name (char *string)
{
  name = dbe_strdup (string);
  dbeSession->dobj_updateHT (this);
}

DbeEA *
DataObject::find_dbeEA (Vaddr EA)
{
  DbeEA *dbeEA;
  int left = 0;
  int right = EAs->size () - 1;
  while (left <= right)
    {
      int index = (left + right) / 2;
      dbeEA = EAs->fetch (index);
      if (EA < dbeEA->eaddr)
	right = index - 1;
      else if (EA > dbeEA->eaddr)
	left = index + 1;
      else
	return dbeEA;
    }

  // None found, create a new one
  dbeEA = new DbeEA (this, EA);
  EAs->insert (left, dbeEA);
  return dbeEA;
}
