/*
   Copyright (C) 2010, 2011 Red Hat, Inc.
   This file is part of Red Hat elfutils.

   Red Hat elfutils 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; version 2 of the License.

   Red Hat elfutils 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 Red Hat elfutils; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.

   Red Hat elfutils is an included package of the Open Invention Network.
   An included package of the Open Invention Network is a package for which
   Open Invention Network licensees cross-license their patents.  No patent
   license is granted, either expressly or impliedly, by designation as an
   included package.  Should you wish to participate in the Open Invention
   Network licensing program, please visit www.openinventionnetwork.com
   <http://www.openinventionnetwork.com>.  */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "highlevel_check.hh"
#include "all-dies-it.hh"
#include "option.hh"
#include "pri.hh"
#include "files.hh"

#include <libintl.h>

#include <sstream>
#include <bitset>

using elfutils::dwarf;

#define DIE_OPTSTRING				\
  "}[,...]"

global_opt<string_option> opt_ignore
  ("Skip certain DIEs.  class may be one of single_addr, artificial, inlined, \
inlined_subroutine, no_coverage, mutable, or immutable.",
   "class[,...]", "ignore");

global_opt<string_option> opt_dump
  ("Dump certain DIEs.  For classes, see option 'ignore'.",
   "class[,...]", "dump");

global_opt<string_option> opt_tabulation_rule
  ("Rule for sorting results into buckets. start is either integer 0..100, \
or special value 0.0 indicating cases with no coverage whatsoever \
(i.e. not those that happen to round to 0%).",
   "start[:step][,...]", "tabulate");

// where.c needs to know how to format certain wheres.  The module
// doesn't know that we don't use these :)
extern "C"
bool
show_refs ()
{
  return false;
}

#define DIE_TYPES		\
  TYPE(single_addr)		\
  TYPE(artificial)		\
  TYPE(inlined)			\
  TYPE(inlined_subroutine)	\
  TYPE(no_coverage)		\
  TYPE(mutable)			\
  TYPE(immutable)

struct tabrule
{
  int start;
  int step;
  tabrule (int a_start, int a_step)
    : start (a_start), step (a_step)
  {}
  bool operator < (tabrule const &other) const {
    return start < other.start;
  }
};

// Sharp 0.0% coverage (i.e. not a single address byte is covered)
const int cov_00 = -1;

struct tabrules_t
  : public std::vector<tabrule>
{
  tabrules_t (std::string const &rule)
  {
    std::stringstream ss;
    ss << rule;

    std::string item;
    while (std::getline (ss, item, ','))
      {
	if (item.empty ())
	  continue;
	int start;
	int step;
	char const *ptr = item.c_str ();

	if (item.length () >= 3
	    && std::strncmp (ptr, "0.0", 3) == 0)
	  {
	    start = cov_00;
	    ptr += 3;
	  }
	else
	  start = std::strtol (ptr, const_cast<char **> (&ptr), 10);

	if (*ptr == 0)
	  step = 0;
	else
	  {
	    if (*ptr != ':')
	      {
		step = 0;
		goto garbage;
	      }
	    else
	      ptr++;

	    step = std::strtol (ptr, const_cast<char **> (&ptr), 10);
	    if (*ptr != 0)
	    garbage:
	      std::cerr << "Ignoring garbage at the end of the rule item: '"
			<< ptr << '\'' << std::endl;
	  }

	push_back (tabrule (start, step));
      }

    push_back (tabrule (100, 0));
    std::sort (begin (), end ());
  }

  void next ()
  {
    if (at (0).step == 0)
      erase (begin ());
    else
      {
	if (at (0).start == cov_00)
	  at (0).start = 0;
	at (0).start += at (0).step;
	if (size () > 1)
	  {
	    if (at (0).start > at (1).start)
	      erase (begin ());
	    while (size () > 1
		   && at (0).start == at (1).start)
	      erase (begin ());
	  }
      }
  }

  bool match (int value) const
  {
    return at (0).start == value;
  }
};

#define TYPE(T) dt_##T,
  enum die_type_e
    {
      DIE_TYPES
      dt__count
    };
#undef TYPE

class die_type_matcher
  : public std::bitset<dt__count>
{
  class invalid {};
  std::pair<die_type_e, bool>
  parse (std::string &desc)
  {
    bool val = true;
    if (desc == "")
      throw invalid ();

#define TYPE(T)					\
    if (desc == #T)				\
      return std::make_pair (dt_##T, val);
    DIE_TYPES
#undef TYPE

      throw invalid ();
  }

public:
  die_type_matcher (std::string const &rule)
  {
    std::stringstream ss;
    ss << rule;

    std::string item;
    while (std::getline (ss, item, ','))
      try
	{
	  std::pair<die_type_e, bool> const &ig = parse (item);
	  set (ig.first, ig.second);
	}
      catch (invalid &i)
	{
	  std::cerr << "Invalid die type: " << item << std::endl;
	}
  }
};

class mutability_t
{
  bool _m_is_mutable;
  bool _m_is_immutable;

public:
  mutability_t ()
    : _m_is_mutable (false)
    , _m_is_immutable (false)
  {
  }

  void set (bool what)
  {
    if (what)
      _m_is_mutable = true;
    else
      _m_is_immutable = true;
  }

  void set_both ()
  {
    set (true);
    set (false);
  }

  void locexpr (Dwarf_Op *expr, size_t len)
  {
    // We scan the expression looking for DW_OP_{bit_,}piece
    // operators which mark ends of sub-expressions to us.
    bool m = false;
    for (size_t i = 0; i < len; ++i)
      switch (expr[i].atom)
	{
	case DW_OP_implicit_value:
	case DW_OP_stack_value:
	  m = true;
	  break;

	case DW_OP_bit_piece:
	case DW_OP_piece:
	  set (m);
	  m = false;
	  break;
	};
    set (m);
  }

  bool is_mutable () const { return _m_is_mutable; }
  bool is_immutable () const { return _m_is_immutable; }
};

struct error
  : public std::runtime_error
{
  explicit error (std::string const &what_arg)
    : std::runtime_error (what_arg)
  {}
};

// Look through the stack of parental dies and return the non-empty
// ranges instance closest to the stack top (i.e. die_stack.end ()).
dwarf::ranges
find_ranges (std::vector<dwarf::debug_info_entry> const &die_stack)
{
  for (auto it = die_stack.rbegin (); it != die_stack.rend (); ++it)
    if (!it->ranges ().empty ())
      return it->ranges ();
  throw error ("no ranges for this DIE");
}

bool
is_inlined (dwarf::debug_info_entry const &die)
{
  dwarf::debug_info_entry::attributes_type::const_iterator it
    = die.attributes ().find (DW_AT_inline);
  if (it != die.attributes ().end ())
    {
      char const *name = (*it).second.dwarf_constant ().name ();
      return std::strcmp (name, "declared_inlined") == 0
	|| std::strcmp (name, "inlined") == 0;
    }
  return false;
}

void
process(Dwarf *c_dw, dwarf const &dw)
{
  // map percentage->occurrences.  Percentage is cov_00..100, where
  // 0..100 is rounded-down integer division.
  std::map<int, unsigned long> tally;
  unsigned long total = 0;
  for (int i = 0; i <= 100; ++i)
    tally[i] = 0;

  tabrules_t tabrules (opt_tabulation_rule.seen ()
		       ? opt_tabulation_rule.value () : "10:10");
  die_type_matcher ignore (opt_ignore.seen () ? opt_ignore.value () : "");
  die_type_matcher dump (opt_dump.seen () ? opt_dump.value () : "");
  std::bitset<dt__count> interested = ignore | dump;
  bool interested_mutability
    = interested.test (dt_mutable) || interested.test (dt_immutable);

  for (all_dies_iterator<dwarf> it = all_dies_iterator<dwarf> (dw);
       it != all_dies_iterator<dwarf> (); ++it)
    {
      std::bitset<dt__count> die_type;
      dwarf::debug_info_entry const &die = *it;

      // We are interested in variables and formal parameters
      bool is_formal_parameter = die.tag () == DW_TAG_formal_parameter;
      if (!is_formal_parameter && die.tag () != DW_TAG_variable)
	continue;

      dwarf::debug_info_entry::attributes_type const &attrs
	= die.attributes ();

      // ... except those that are just declarations
      if (attrs.find (DW_AT_declaration) != attrs.end ())
	continue;

      if (ignore.test (dt_artificial)
	  && attrs.find (DW_AT_artificial) != attrs.end ())
	continue;

      // Of formal parameters we ignore those that are children of
      // subprograms that are themselves declarations.
      std::vector<dwarf::debug_info_entry> const &die_stack = it.stack ();
      dwarf::debug_info_entry const &parent = *(die_stack.rbegin () + 1);
      if (is_formal_parameter)
	if (parent.tag () == DW_TAG_subroutine_type
	    || (parent.attributes ().find (DW_AT_declaration)
		!= parent.attributes ().end ()))
	  continue;

      if (interested.test (dt_inlined)
	  || interested.test (dt_inlined_subroutine))
	{
	  bool inlined = false;
	  bool inlined_subroutine = false;
	  for (std::vector<dwarf::debug_info_entry>::const_reverse_iterator
		 stit = die_stack.rbegin (); stit != die_stack.rend (); ++stit)
	    {
	      if (interested.test (dt_inlined)
		  && stit->tag () == DW_TAG_subprogram
		  && is_inlined (*stit))
		{
		  inlined = true;
		  if (interested.test (dt_inlined_subroutine)
		      && inlined_subroutine)
		    break;
		}
	      if (interested.test (dt_inlined_subroutine)
		  && stit->tag () == DW_TAG_inlined_subroutine)
		{
		  inlined_subroutine = true;
		  if (interested.test (dt_inlined)
		      && inlined)
		    break;
		}
	    }

	  if (inlined)
	    {
	      if (ignore.test (dt_inlined))
		continue;
	      die_type.set (dt_inlined);
	    }
	  if (inlined_subroutine)
	    {
	      if (ignore.test (dt_inlined_subroutine))
		continue;
	      die_type.set (dt_inlined_subroutine, inlined_subroutine);
	    }
	}

      // Unfortunately the location expression is not yet wrapped
      // in c++, so we need to revert back to C code.
      Dwarf_Die die_c_mem,
	*die_c = dwarf_offdie (c_dw, die.offset (), &die_c_mem);
      assert (die_c != NULL);

      Dwarf_Attribute locattr_mem,
	*locattr = dwarf_attr_integrate (die_c, DW_AT_location, &locattr_mem);

      // Also ignore extern globals -- these have DW_AT_external and
      // no DW_AT_location.
      if (attrs.find (DW_AT_external) != attrs.end () && locattr == NULL)
	continue;

      /*
      Dwarf_Attribute name_attr_mem,
	*name_attr = dwarf_attr_integrate (die_c, DW_AT_name, &name_attr_mem);
      std::string name = name_attr != NULL
	? dwarf_formstring (name_attr)
	: (dwarf_hasattr_integrate (die_c, DW_AT_artificial)
	   ? "<artificial>" : "???");

      std::cerr << "die=" << std::hex << die.offset ()
		<< " '" << name << '\'';
      */

      int coverage;
      Dwarf_Op *expr;
      size_t len;
      mutability_t mut;

      // consts need no location
      if (attrs.find (DW_AT_const_value) != attrs.end ())
	{
	  coverage = 100;
	  if (interested_mutability)
	    mut.set (true);
	}

      // no location
      else if (locattr == NULL)
	{
	  coverage = cov_00;
	  if (interested_mutability)
	    mut.set_both ();
	}

      // non-list location
      else if (dwarf_getlocation (locattr, &expr, &len) == 0)
	{
	  // Globals and statics have non-list location that is a
	  // singleton DW_OP_addr expression.
	  if (len == 1 && expr[0].atom == DW_OP_addr)
	    {
	      if (ignore.test (dt_single_addr))
		continue;
	      die_type.set (dt_single_addr);
	    }
	  if (interested_mutability)
	    mut.locexpr (expr, len);
	  coverage = (len == 0) ? cov_00 : 100;
	}

      // location list
      else
	{
	  try
	    {
	      dwarf::ranges ranges (find_ranges (die_stack));
	      size_t length = 0;
	      size_t covered = 0;

	      // Arbitrarily assume that there will be no more than 10
	      // expressions per address.
	      size_t nlocs = 10;
	      Dwarf_Op *exprs[nlocs];
	      size_t exprlens[nlocs];

	      for (dwarf::ranges::const_iterator rit = ranges.begin ();
		   rit != ranges.end (); ++rit)
		{
		  Dwarf_Addr low = (*rit).first;
		  Dwarf_Addr high = (*rit).second;
		  length += high - low;
		  //std::cerr << " " << low << ".." << high << std::endl;

		  for (Dwarf_Addr addr = low; addr < high; ++addr)
		    {
		      int got = dwarf_getlocation_addr (locattr, addr,
							exprs, exprlens, nlocs);
		      if (got < 0)
			throw ::error (std::string ("dwarf_getlocation_addr: ")
				       + dwarf_errmsg (-1));

		      // At least one expression for the address must
		      // be of non-zero length for us to count that
		      // address as covered.
		      for (int i = 0; i < got; ++i)
			{
			  if (interested_mutability)
			    mut.locexpr (exprs[i], exprlens[i]);
			  if (exprlens[i] > 0)
			    {
			      covered++;
			      break;
			    }
			}
		    }
		}

	      if (length == 0)
		throw ::error ("zero-length range");

	      if (covered == 0)
		coverage = cov_00;
	      else
		coverage = 100 * covered / length;
	    }
	  catch (::error const &e)
	    {
	      std::cerr << "error: " << die_locus (die) << ": "
			<< e.what () << '.' << std::endl;
	      continue;
	    }
	}

      if (coverage == cov_00)
	{
	  if (ignore.test (dt_no_coverage))
	    continue;
	  die_type.set (dt_no_coverage);
	}
      else if (interested_mutability)
	{
	  assert (mut.is_mutable () || mut.is_immutable ());
	  if (mut.is_mutable ())
	    {
	      if (ignore.test (dt_mutable))
		continue;
	      die_type.set (dt_mutable);
	    }
	  if (mut.is_immutable ())
	    {
	      if (ignore.test (dt_immutable))
		continue;
	      die_type.set (dt_immutable);
	    }
	}

      if ((dump & die_type).any ())
	{
#define TYPE(T) << (die_type.test (dt_##T) ? " "#T : "")
	  std::cerr << "dumping" DIE_TYPES << " DIE" << std::endl;
#undef TYPE

	  std::string pad = "";
	  for (auto sit = die_stack.begin (); sit != die_stack.end (); ++sit)
	    {
	      auto const &d = *sit;
	      std::cerr << pad << pri::ref (d) << " "
			<< elfutils::dwarf::tags::name (d.tag ()) << std::endl;
	      for (auto atit = d.attributes ().begin ();
		   atit != d.attributes ().end (); ++atit)
		{
		  auto const &attr = *atit;
		  std::cerr << pad << "    " << to_string (attr) << std::endl;
		}
	      pad += " ";
	    }

	  std::cerr << "empty coverage " << pri::ref (die) << " "
		    << to_string (die) << std::endl;
	}

      tally[coverage]++;
      total++;
      //std::cerr << std::endl;
    }

  unsigned long cumulative = 0;
  unsigned long last = 0;
  int last_pct = cov_00;
  if (total == 0)
    {
      std::cout << "No coverage recorded." << std::endl;
      return;
    }

  std::cout << "cov%\tsamples\tcumul" << std::endl;
  for (int i = cov_00; i <= 100; ++i)
    {
      cumulative += tally.find (i)->second;
      if (tabrules.match (i))
	{
	  long int samples = cumulative - last;

	  // The case 0.0..x should be printed simply as 0
	  if (last_pct == cov_00 && i > cov_00)
	    last_pct = 0;

	  if (last_pct == cov_00)
	    std::cout << "0.0";
	  else
	    std::cout << std::dec << last_pct;

	  if (last_pct != i)
	    std::cout << ".." << i;
	  std::cout << "\t" << samples
		    << '/' << (100*samples / total) << '%'
		    << "\t" << cumulative
		    << '/' << (100*cumulative / total) << '%'
		    << std::endl;
	  last = cumulative;
	  last_pct = i + 1;

	  tabrules.next ();
	}
    }
}

int
main(int argc, char *argv[])
{
  /* Set locale.  */
  setlocale (LC_ALL, "");

  /* Initialize the message catalog.  */
  textdomain (PACKAGE_TARNAME);

  /* Parse and process arguments.  */
  argppp argp (global_opts ());
  int remaining;
  argp.parse (argc, argv, 0, &remaining);

  if (remaining == argc)
    {
      fputs (gettext ("Missing file name.\n"), stderr);
      argp.help (stderr, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
		 program_invocation_short_name);
      std::exit (1);
    }

  bool only_one = remaining + 1 == argc;
  do
    {
      try
	{
	  char const *fname = argv[remaining];
	  if (!only_one)
	    std::cout << std::endl << fname << ":" << std::endl;

	  int fd = files::open (fname);
	  Dwfl *dwfl = files::open_dwfl ();
	  Dwarf *c_dw = files::open_dwarf (dwfl, fname, fd);
	  dwarf dw = files::open_dwarf (c_dw);

	  process (c_dw, dw);

	  close (fd);
	  dwfl_end (dwfl);
	}
      catch (std::runtime_error &e)
	{
	  std::cerr << "error: "
		    << e.what () << '.' << std::endl;
	  continue;
	}
    }
  while (++remaining < argc);
}
